如何避免生成序列化构造函数访问器问题?

时间:2010-06-04 01:51:06

标签: java serialization constructor garbage-collection accessor

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

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

3 个答案:

答案 0 :(得分: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选项会禁用通胀机制,而是立即使用生成的访问权限,因此您不需要该选项。

答案 1 :(得分:2)

  

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

如果您的应用程序使用反射是不可避免的,您可以尝试使用CMS garbage collector来尽量减少世界各地GC的影响。

答案 2 :(得分:0)

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

  

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

     

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

它们似乎只是暂时用于序列化/反序列化给定的对象类。正如文章所指出的那样,这些可能是使用SoftReferences进行的,因此请确保您的应用程序有足够的内存,并且这些内存的回收频率会降低。

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