Permanent Generation : does the capacity of default value get fixed or will it grow as required?
we are noticing that our customer running Solaris 10 is having Permanent GC grow from 50% to 97% of capacity. This JVM was using the default value of "permgen" (we did NOT pass any custom Permgen FLAG to the JVM).
Instead of running at 97% permgen space in production, should we set a higher value of PermGen ?
P.S : we're using JDK 1.6.0_23 on solaris 10.
UPDATE Should we think that anytime soon, it could do a OutOfMemoryError ? 开发者_JAVA技巧OR is it possible that the JVM will increase capacity so that the usage falls below 97% ?
PermGen will grow up to a predetermined maximum (which you can set from the command line) and then stop. The PermGen area holds primarily class definitions, and usually you run out of PermGen in applications that load a lot of classes and don't release them -- either because they're just big or, in web apps, because something is accidentally holding on to a class after its classloader has been released. You need to determine whether PermGen keeps growing and growing, or whether it eventually stabilizes.
PermGen space used may grow over time to certain memory leaks / bugs in the application code, or in the libraries you are using.
For example we frequently see problems when running a webapp in Apache Tomcat which uses Spring and log4j if the webapp instance is reloaded too many times, apparently log4j has some issues where it does not properly unload certain classes from the classloader.
So yes, it is possible to have leaks that cause PermGen space to grow over time, just like normal memory leaks.
Your reasoning is a little unclear.
If you anticipate a failure, why not take the defensive approach and increase the -XX:MaxPermSize
right away?
We are noticing that our customer running Solaris 10 is having Permanent GC grow from 50% to 97% of capacity.
Was there a significant code change in your customer's application prior to noticing the spike in perm gen? Or has it always been like this (going from 50% to 97%)?
I guess it doesn't really matter at this point, but in some cases, spikes like this should be detectable during system testing (assuming your team has visibility in your customers' system testing cycle.)
One thing for certain is that running at 97% is way too much close to the max for comfort, and you will have to play with the max perm gen parameters (and as a consequence with other heap parameters... most likely.)
This JVM was using the default value of "permgen" (we did NOT pass any custom Permgen FLAG to the JVM).
Not a good idea. You should (read must) always characterize your (or your customers) applications before deployment. Either your customers should tell you what params they need, or your team must determine those during UAT and system test cycles (assuming you have visibility on those; see above.)
Should we think that anytime soon, it could do a OutOfMemoryError ?
It is not an inevitability, but it is a possibility (especially if the app has not been subjected to the max possible load yet.) It is also possible if the spike is a recent phenomenon. In that case, due, most likely, to a code change, or a previously unknown condition due to other factors (a patch in the OS, in the container, change in customer traffic, change in the db, etc.)
Instead of running at 97% permgen space in production, should we set a higher value of PermGen ?
IMO, yes. If you (or your customer) can characterize or estimate the app's memory (both perm and heap) requirements (as well as current and possible future traffic), you should give yourself a 10%-20% margin, just in case. Anything less is just playing with fire. Anything more most likely will be wasteful.
Memory might be cheap, but application performance and stability are not ;)
If you haven't use visualgc, you should. It's a good tool to visually inspect what's going with the different segments in your JVM memory. There is also visualvm, which is more powerful and versatile, yet, the visualgc UI presentation of readings is specifically suitable for this task.
P.S : we're using JDK 1.6.0_23 on solaris 10.
I don't think that should matter. What is your application container (if your app is running in one.) You might want to edit your post to include this.
I believe that the JVM will use the same strategy for expanding the permgen heap as it does with the normal heap.
- The permgen heap size starts at a configurable initial size
- If the ratio of used permgen heap to permgen heap size is greater than a given value after a permgen collection, it will be expanded.
- The permgen heap size may grow to a configurable maximum size
Now if the permgen heap is 97% full after GC, then it is highly likely that permgen has already been expanded to the maximum size configured (the default in your case).
It is impossible to say where an OOME is imminent. (It depends on how your application behaves, and what is causing it to increase permgen usage.) However, it would be prudent to:
- increase a larger maximum permgen heap size in the short term, and
- track down what is causing increased permgen heap usage.
There is a maximum PermGen size and you get an OutOfMemoryError when this si reached. However if you are 97% full it doesn't mean you are at your maximum, just 97% of the space allocated at that time. (In another 3% it will have to grow the space if it can)
精彩评论