我们有一个接收 SOAP 请求的 Java 应用程序,在收到大量请求后,我们注意到 GC 停止了世界卸载大量 GeneratedSerializationConstructorAccessor 类。这是一个很大的性能影响。
有谁知道如何避免这种情况或至少显着减少创建的 GeneratedSerializationConstructorAccessor 类的数量?
我们有一个接收 SOAP 请求的 Java 应用程序,在收到大量请求后,我们注意到 GC 停止了世界卸载大量 GeneratedSerializationConstructorAccessor 类。这是一个很大的性能影响。
有谁知道如何避免这种情况或至少显着减少创建的 GeneratedSerializationConstructorAccessor 类的数量?
使用以下选项之一:
-Dsun.reflect.inflationThreshold=30
在本地访问器“膨胀”到生成的访问器之前,增加通过构造函数/方法/字段的调用次数。默认值为 15。
-Dsun.reflect.inflationThreshold=0
完全禁用通货膨胀。有趣的是,这个选项似乎不会影响构造函数,但它确实适用于方法。
您可以使用简单的测试应用程序测试选项:
public class a {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 20; i++) {
a.class.getDeclaredConstructor(null).newInstance(null);
}
}
private static int x;
public a() {
new Throwable("" + x++).printStackTrace();
}
}
编辑(2013 年 12 月 29 日):该-Dsun.reflect.noInflation=true
选项禁用膨胀机制,而是立即使用生成的访问器,因此您不需要该选项。
[...] 我们注意到 GC 阻止了世界卸载大量 GeneratedSerializationConstructorAccessor 类。这是一个很大的性能影响。
如果您的应用程序使用反射是无法避免的,您可以尝试使用CMS 垃圾收集器来最小化 stop-the-world GC 的影响。
来自http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2006-11/msg00122.html
这些类是反射机制的一部分。从 Java 1.3 开始,反射已经通过生成类来执行访问来实现。它的使用速度要快得多,但需要更长的时间来创建并扰乱永久代。
序列化使用它们来读/写字段、执行方法(readObject、writeObject、readObjectNoData、readResolve)并调用不可序列化的基类构造函数(最后一个代码是不可验证的)。
看来它们只是暂时用于序列化/反序列化给定的对象类。正如文章所指出的,这些可能是使用 SoftReferences 保存的,因此请确保您的应用程序有足够的内存,并且这些内存将被较少地回收。
令人惊讶的是,似乎没有任何其他解决方案。