IBM Support

使用反射代理类加载器的潜在内存使用问题

Technote (troubleshooting)


问题(摘要)

大量的类加载器 sun/reflect/DelegatingClassLoader,用来加载sun/reflect/GeneratedMethodAccessor类,可能导致潜在的占用大量本机内存空间问题。

症状

应用服务器进程占用的内存会显著增大。您还有可能遇到抛出的内存溢出错误。


原因

当使用Java反射时,Java虚拟机有两种方法获取被反射的类的信息。它可以使用一个JNI存取器。如果使用Java字节码存取器,则需要拥有它自己的Java类和类加载器(sun/reflect/GeneratedMethodAccessor类和sun/reflect/DelegatingClassLoader)。这些类和类加载器使用本机内存。字节码存取器也可以被JIT编译,这样会增加本机内存的使用。如果Java反射被频繁使用,会显著地增加本机内存的使用。

Java虚拟机会首先使用JNI存取器,然后在访问了同一个类若干次后,会改为使用Java字节码存取器。这种当Java虚拟机从JNI存取器改为字节码存取器的行为被称为膨胀。幸运的是,我们可以通过一个Java属性控制这种行为。属性sun.reflect.inflationThreshold会告诉Java虚拟机使用JNI存取器多少次。如果设为0,则总是使用JNI存取器。由于字节码存取器比JNI存取器使用更多本机内存,当我们看到大量Java反射时,最好使用JNI存取器。我们只需要设置inflationThreshold属性值为0即可。


诊断问题

如果在javacore或heapdump中有大量sun/reflect/DelegatingClassLoader类加载器,您可能遇到了此问题。

解决问题

设置Java属性sun.reflect.inflationThreshold值为0。


1. 访问WebSphere应用程序服务器管理控制台
服务器 > 应用程序服务器 > 服务器名称
2. 在服务器基础结构部分,展开Java和进程管理,选择进程定义
3. 在其他属性部分选择Java虚拟机,在通用JVM参数输入框里添加以下字符串
-Dsun.reflect.inflationThreshold=0
4. 点击“确定”,保存至主配置。
需要重启应用程序服务器使设置生效。

相关信息

1566549

Document information

More support for: WebSphere Application Server
Out of Memory

Software version: 6.1, 7.0, 8.0

Operating system(s): AIX, HP-UX, Linux, Solaris, Windows

Reference #: 1636746

Modified date: 09 May 2013


Translate this page: