6

我们有一个接收 SOAP 请求的 Java 应用程序,在收到大量请求后,我们注意到 GC 停止了世界卸载大量 GeneratedSerializationConstructorAccessor 类。这是一个很大的性能影响。

有谁知道如何避免这种情况或至少显着减少创建的 GeneratedSerializationConstructorAccessor 类的数量?

4

3 回答 3

5

使用以下选项之一:

-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选项禁用膨胀机制,而是立即使用生成的访问器,因此您不需要该选项。

于 2010-06-04T03:36:51.687 回答
2

[...] 我们注意到 GC 阻止了世界卸载大量 GeneratedSerializationConstructorAccessor 类。这是一个很大的性能影响。

如果您的应用程序使用反射是无法避免的,您可以尝试使用CMS 垃圾收集器来最小化 stop-the-world GC 的影响。

于 2010-06-30T08:35:46.850 回答
0

来自http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2006-11/msg00122.html

这些类是反射机制的一部分。从 Java 1.3 开始,反射已经通过生成类来执行访问来实现。它的使用速度要快得多,但需要更长的时间来创建并扰乱永久代。

序列化使用它们来读/写字段、执行方法(readObject、writeObject、readObjectNoData、readResolve)并调用不可序列化的基类构造函数(最后一个代码是不可验证的)。

看来它们只是暂时用于序列化/反序列化给定的对象类。正如文章所指出的,这些可能是使用 SoftReferences 保存的,因此请确保您的应用程序有足够的内存,并且这些内存将被较少地回收。

令人惊讶的是,似乎没有任何其他解决方案。

于 2010-06-04T01:55:37.020 回答