java.lang.OutOfMemoryError:PermGen space:java reflection [英] java.lang.OutOfMemoryError: PermGen space: java reflection

查看:97
本文介绍了java.lang.OutOfMemoryError:PermGen space:java reflection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在代码中使用java反射:

I use java reflection in the code like this:

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

我用 jprofiler 可以看到很多类似的这个 sun.reflect.GeneratedMethodAccessor11

I use jprofiler can see many class like this sun.reflect.GeneratedMethodAccessor11

这些课程每次通话都会增加

these classes are increased per call

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

我认为这就是为什么PermGen空间增加,如何清理这些类?

I think this is why PermGen space increase, how to clean these classes?

推荐答案

有一篇非常好的文章讨论反射委托类加载器中的潜在本机内存使用

There is a pretty nice article discussing about potential native memory use in reflection delegating classloaders.


使用Java反射时,JVM有两个访问反映的类的
信息的方法。它可以使用JNI访问器,
或Java字节码访问器。如果它使用Java字节码访问器,那么
它需要有自己的Java类和类加载器
(sun / reflect / GeneratedMethodAccessor类和
sun / reflect / DelegatingClassLoader)。这些类和类加载器
使用本机内存。访问器字节码也可以得到JIT编译,
这将进一步增加本机​​内存的使用。如果经常使用Java
反射,这可能会增加大量
的本机内存使用量。 JVM将首先使用JNI访问器,然后在同一个类上进行一些访问后,
将更改为使用
Java字节码访问器。当JVM
从JNI访问器更改为字节码访问器时,这称为通胀。幸运的是,
我们可以使用Java属性来控制它。
sun.reflect.inflationThreshold属性告诉JVM使用JNI访问器的
次数。如果设置为0,则始终使用JNI
访问器。由于字节码访问器使用比JNI更多的
本机内存,如果我们看到很多Java
反射,我们将希望使用JNI访问器。要做到这一点,我们只需
需要将inflationThreshold属性设置为零。

When using Java reflection, the JVM has two methods of accessing the information on the class being reflected. It can use a JNI accessor, or a Java bytecode accessor. If it uses a Java bytecode accessor, then it needs to have its own Java class and classloader (sun/reflect/GeneratedMethodAccessor class and sun/reflect/DelegatingClassLoader). Theses classes and classloaders use native memory. The accessor bytecode can also get JIT compiled, which will increase the native memory use even more. If Java reflection is used frequently, this can add up to a significant amount of native memory use. The JVM will use the JNI accessor first, then after some number of accesses on the same class, will change to use the Java bytecode accessor. This is called inflation, when the JVM changes from the JNI accessor to the bytecode accessor. Fortunately, we can control this with a Java property. The sun.reflect.inflationThreshold property tells the JVM what number of times to use the JNI accessor. If it is set to 0, then the JNI accessors are always used. Since the bytecode accessors use more native memory than the JNI ones, if we are seeing a lot of Java reflection, we will want to use the JNI accessors. To do this, we just need to set the inflationThreshold property to zero.

设置 sun .reflect.inflationThreshold 到0 -Dsun.reflect.inflationThreshold = 0 会为你做一些技巧。

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

这篇关于java.lang.OutOfMemoryError:PermGen space:java reflection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆