3

为了打印web应用的GC日志,在tomcat启动前,添加如下参数:

-Xms256m 
-Xmx512m 
-XX:PermSize=128M 
-XX:MaxPermSize=512M
-Xloggc:D:/TomcatGc.log

但是,终端上会连续打印以下信息。

[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor339]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor336]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor341]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor342]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor340]

我的问题是:

  1. 为什么会生成这些类?我想了解这个概念,但找不到任何有关它的信息。

  2. 如何防止 GC 卸载它们?

4

3 回答 3

5

这是因为(可能是您在应用程序中使用反射)堆空间不足,并GC试图通过卸载未使用的对象来释放一些内存,这就是您看到的原因Unloading class sun.reflect.GeneratedSerializationConstructorAccessor

更多信息--> http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2006-11/msg00122.html

于 2013-05-23T08:24:13.390 回答
5

不同类型的访问器

方法访问器和构造器访问器要么是原生的,要么是生成的。这意味着我们要么对方法使用 NativeMethodAccessorImpl 或 GeneratedMethodAccessor,对构造函数使用 NativeConstructorAccessorImpl 和 GeneratedConstructorAccessor。访问器将是本地的或生成的,并由两个系统属性控制和决定:

  1. sun.reflect.noInflation = false(默认值为 false)
  2. sun.reflect.inflationThreshold = 15(默认值为 15)

当 sun.reflect.noInflation 设置为 true 时,将始终生成使用的访问器,并且系统属性 sun.reflect.inflationThreshold 没有任何意义。当 sun.reflect.noInflation 为 false 并且 sun.reflect.inflationThreshold 设置为 15(如果未指定,则为默认行为),则意味着对于构造函数(或方法)的前 15 次访问,本机生成器将被使用,然后将提供一个生成的访问器(来自 ReflectionFactory)以供使用。

本机访问器使用本机调用来访问信息,而生成的访问器全是字节码,因此速度非常快。另一方面,生成的访问器需要时间来实例化和加载(基本上是膨胀,因此控制它的系统属性的名称包括“膨胀”字)。

更多细节可以在原始博客中找到

于 2016-03-07T13:55:40.477 回答
2

@pXL 已经回答了您的第一个问题,但是:

  1. 如何防止 GC 卸载它们?

你不能。你到底为什么想要?它们不再被引用,这意味着没有可访问的实例,因此它们有资格进行垃圾收集,因此它们正在被垃圾收集,这意味着卸载。

阻止这种情况既无意义又适得其反。

于 2013-05-23T08:32:42.303 回答