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

问题(摘要)

大量的类加载器 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值