Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.lang.OutOfMemoryError:PermGen空间:java反射_Java_Reflection - Fatal编程技术网

java.lang.OutOfMemoryError:PermGen空间: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

我在代码中使用java反射,如下所示:

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_值)即可。