Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>Causes of growing Perm Gen</strong></p> <ul> <li>Lots of classes, especially JSPs.</li> <li>Lots of static variables.</li> <li>There is a classloader leak. </li> </ul> <p>For those that don't know, here is a simple way to think about how the PremGen fills up. The Young Gen doesn't get enough time to let things expire and so they get moved up to Old Gen space. The Perm Gen holds the classes for the objects in the Young and Old Gen. When the objects in the Young or Old Gen get collected and the class is no longer being referenced then it gets 'unloaded' from the Perm Gen. If the Young and Old Gen don't get GC'd then neither does the Perm Gen and once it fills up it needs a Full stop-the-world GC. For more info see <a href="https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation">Presenting the Permanent Generation</a>.</p> <hr> <p><strong>Switching to CMS</strong></p> <p>I know you are using G1 but if you do switch to the Concurrent Mark Sweep (CMS) low pause collector <code>-XX:+UseConcMarkSweepGC</code>, try enabling class unloading and permanent generation collections by adding <code>-XX:+CMSClassUnloadingEnabled</code>.</p> <hr> <p><strong>The Hidden Gotcha'</strong></p> <p>If you are using JBoss, RMI/DGC has the gcInterval set to 1 min. The RMI subsystem forces a full garbage collection once per minute. This in turn forces promotion instead of letting it get collected in the Young Generation.</p> <p>You should change this to at least 1 hr if not 24 hrs, in order for the the GC to do proper collections. </p> <pre><code>-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 </code></pre> <hr> <p><strong>List of every JVM option</strong></p> <p>To see all the options, run this from the cmd line.</p> <pre><code>java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version </code></pre> <p>If you want to see what JBoss is using then you need to add the following to your <code>standalone.xml</code>. You will get a list of every JVM option and what it is set to. NOTE: it must be in the JVM that you want to look at to use it. If you run it external you won't see what is happening in the JVM that JBoss is running on. </p> <pre><code>set "JAVA_OPTS= -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal %JAVA_OPTS%" </code></pre> <p>There is a shortcut to use when we are only interested in the modified flags.</p> <pre><code>-XX:+PrintcommandLineFlags </code></pre> <hr> <p><strong>Diagnostics</strong></p> <p>Use <a href="http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html">jmap</a> to determine what classes are consuming permanent generation space. Output will show </p> <ul> <li>class loader</li> <li># of classes</li> <li>bytes</li> <li>parent loader</li> <li>alive/dead</li> <li>type</li> <li><p>totals</p> <pre><code>jmap -permstat JBOSS_PID &gt;&amp; permstat.out </code></pre></li> </ul> <hr> <p><strong><a href="http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html">JVM Options</a></strong></p> <p>These settings worked for me but depending how your system is set up and what your application is doing will determine if they are right for you.</p> <ul> <li><p><code>-XX:SurvivorRatio=8</code> – Sets survivor space ratio to 1:8, resulting in larger survivor spaces (the smaller the ratio, the larger the space). The SurvivorRatio is the size of the Eden space compared to one survivor space. Larger survivor spaces allow short lived objects a longer time period to die in the young generation.</p></li> <li><p><code>-XX:TargetSurvivorRatio=90</code> – Allows 90% of the survivor spaces to be occupied instead of the default 50%, allowing better utilization of the survivor space memory.</p></li> <li><p><code>-XX:MaxTenuringThreshold=31</code> – To prevent premature promotion from the young to the old generation . Allows short lived objects a longer time period to die in the young generation (and hence, avoid promotion). A consequence of this setting is that minor GC times can increase due to additional objects to copy. This value and survivor space sizes may need to be adjusted so as to balance overheads of copying between survivor spaces versus tenuring objects that are going to live for a long time. The default settings for CMS are SurvivorRatio=1024 and MaxTenuringThreshold=0 which cause all survivors of a scavenge to be promoted. This can place a lot of pressure on the single concurrent thread collecting the tenured generation. Note: when used with -XX:+UseBiasedLocking, this setting should be 15.</p></li> <li><p><code>-XX:NewSize=768m</code> – allow specification of the initial young generation sizes</p></li> <li><p><code>-XX:MaxNewSize=768m</code> – allow specification of the maximum young generation sizes</p></li> </ul> <p>Here is a more extensive <a href="http://web.archive.org/web/20110430195227/http://blogs.sun.com/watt/resource/jvm-options-list.html">JVM options</a> list. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload