I am struggling with an outOfMemory PermGen issue that has been showing up recently. One of the log snippets that was saved when error appeared:
java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findClass(ModuleImpl.java:1872)
at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:720)
at org.apache.felix.framework.ModuleImpl.access$300(ModuleImpl.java:73)
at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1733)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
I've increased max perm size -XX:MaxPermGen=128m
but this is just a temporary solution because I am preety sure we are facing some memory leak here. The web part of our applications is deployed on jetty (jsf + icefaces). Clicking on random components increases the memory used - I am monitoring it with jstat -gcold
and nearly every hit means 3-4kb more. I've added -XX:+TraceClassLoading
to the jvm params and see many sun.reflect.GeneratedConstructorAccessor
and sun.reflect.GeneratedMethodAccessor
being logged when there is any action on the web user interface. I also made a heap dump when 99% of permgen was used. I used YourKit profiler to analyze the heap. In the class loader tab there are loaads of sun.reflect.DelegatingClassLoader
rows with 1 class for each. What might be causing the memory to constantly grow? Any help will be really appreciated.
thanks in advance, Lukasz
The default maximum memory size for 32-bit JVM is 64 MB and 82 MB for the 64-bit version. However, we can change the default size with the JVM options: -XX:PermSize=[size] is the initial or minimum size of the PermGen space. -XX:MaxPermSize=[size] is the maximum size.
In the place of PermGen, a new feature called Meta Space has been introduced. MetaSpace grows automatically by default. Here, the garbage collection is automatically triggered when the class metadata usage reaches its maximum metaspace size. It is removed from java 8.
On the Sun JVM, reflective access to properties and methods is initially performed by calling through JNI into the JVM implementation. If the JVM notices that a method or field is being accessed by reflection a lot, it will generate bytecode to do the same thing -- a mechanism that it calls "inflation". This has an initial speed hit, but after that runs about 20 times faster. A big win if you do a lot of reflection.
That bytecode lives in classes created by DelegatingClassLoader instances and take up permgen space. If it is a problem, you can turn inflation off by setting the system property sun.reflect.inflationThreshold to 0 (zero).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With