java.lang.OutOfMemoryError:PermGen空间:java反射
我在代码中使用java反射,如下所示:java.lang.OutOfMemoryError:PermGen空间:java反射,java,reflection,Java,Reflection,我在代码中使用java反射,如下所示: Method method = LogFactory.class.getDeclaredMethod("getContextClassLoader"); method.setAccessible(true); ClassLoader classLoader = (ClassLoader)method.invoke(null); LogFactory.release(classLoader); 我使用的jprofiler可以看到许多类似这样的类sun.re
Method method = LogFactory.class.getDeclaredMethod("getContextClassLoader");
method.setAccessible(true);
ClassLoader classLoader = (ClassLoader)method.invoke(null);
LogFactory.release(classLoader);
我使用的jprofiler
可以看到许多类似这样的类sun.reflect.generatedMethodAccessor 11
每次通话都会增加这些课程
sun.reflect.BootstrapConstructorAccessorImpl
sun.reflect.NativeConstructorAccessorImpl
sun.reflect.DelegatingConstructorAccessorImpl
sun.reflect.DelegatingClassLoader
我认为这就是为什么PermGen空间会增加,如何清理这些类?有一篇很好的文章讨论了 当使用Java反射时,JVM有两种访问 关于所反映的类的信息。它可以使用JNI访问器, 或者Java字节码访问器。如果它使用Java字节码访问器,那么 它需要有自己的Java类和类加载器 (阳光/反射/生成方法采集器类和 sun/reflect/DelegatingClassLoader)。这些类和类装入器 使用本机内存。访问器字节码也可以进行JIT编译, 这将进一步增加本机内存的使用。如果Java 如果经常使用反射,这可能会增加大量的反射 本机内存的使用。JVM将首先使用JNI访问器,然后 在同一类上进行若干次访问后,将更改为使用 Java字节码存取器。这被称为通货膨胀,当JVM 从JNI访问器到字节码访问器的更改。幸运的是, 我们可以用Java属性来控制它。这个 sun.reflect.inflationThreshold属性告诉JVM 使用JNI访问器的时间。如果设置为0,则JNI 始终使用访问器。由于字节码访问器使用的 本机内存比JNI内存要多,如果我们看到很多Java的话 反射,我们将希望使用JNI访问器。要做到这一点,我们只需 需要将inflationThreshold属性设置为零
如果您在Oracle JVM上,则只需设置:
-Dsun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
sun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
如果您在IBM JVM上,则需要设置:
-Dsun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
sun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
请注意,两个JVM的解释方式不同。如果您使用的是Oracle JVM,则只需设置:
-Dsun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
sun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
如果您在IBM JVM上,则需要设置:
-Dsun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
sun.reflect.inflationThreshold=2147483647
-Dsun.reflect.inflationThreshold=0
请注意,两个JVM的解释方式都不同
有关更多详细信息,请参阅:
为什么不创建更多的perm空间?也许我应该做更多的测试,我使用eclipse调试代码,然后jprofiler附加它。@JermaineXu默认的perm空间是128MB,但一个月后就达到了。^-^@Fatkun Dsun.reflect.inflationThreshold=0将进行所有调用以使用GeneratedMethodAccessor(jdk6u51 macosx mountain lion)。将其设置为较大的值(Integer.MAX_值)即可。