Java.lang.OutOfMemoryError: PermGen space: reflection in java

I use java reflection in the code as follows:

Method method = LogFactory.class.getDeclaredMethod("getContextClassLoader"); method.setAccessible(true); ClassLoader classLoader = (ClassLoader)method.invoke(null); LogFactory.release(classLoader); 

I use jprofiler to see many classes like this sun.reflect.GeneratedMethodAccessor11

these classes increase per call

 sun.reflect.BootstrapConstructorAccessorImpl sun.reflect.NativeConstructorAccessorImpl sun.reflect.DelegatingConstructorAccessorImpl sun.reflect.DelegatingClassLoader 

I think that’s why PermGen space is increasing, how to clear these classes?

+6
source share
2 answers

There is a pretty good article that discusses the use of potential memory in reflecting the delegation of class loaders .

When using reflection, the Java JVM has two methods of accessing information about the class in question. It can use a JNI accessory, or Java bytecode receiver. If it uses an accessory for Java bytecode, then it should have its own Java class and class loader (sun / reflection / class GeneratedMethodAccessor and sun / reflection / DelegatingClassLoader). Abstracts of classes and class loaders use the built-in memory. The access bytecode can also collect JIT, which will further increase the use of its own memory. If Java reflection is used frequently, this can add up to a significant amount of use of your own memory. First, the JVM will use the JNI accessory, then after a certain number of hits in the same class, the Java bytecode receiver will change to use. This is called inflation when the JVM changes from a JNI accessory to a bytecode accessory. Fortunately, we can manage this using the Java property. The sun.reflect.inflationThreshold value tells the JVM how many to use the JNI accessor. If it is set to 0, then JNI accessors are always used. Since bytecode receivers use more than JNI, if we see a lot of Java, we will use JNI accessors. To do this, we just need to set the infulationThreshold parameter to 0.

Set sun.reflect.inflationThreshold to 0 on -Dsun.reflect.inflationThreshold=0 will do the tricks for you.

+10
source

If you are using an Oracle JVM, you will only need to install:

 sun.reflect.inflationThreshold=2147483647 

If you are on an IBM JVM, you will need to install:

 -Dsun.reflect.inflationThreshold=0 

Note that both JVMs differ in how they are interpreted.

Links for more details:

inflation_system_properties

use of own memory

+1
source

All Articles