JConsole总加载类行为

时间:2013-12-17 14:48:27

标签: java garbage-collection netty jconsole

我监控了一个Java7应用程序几周,我观察了一些我想了解的事情。

从应用程序开始,总加载类的数量不断增长,我认为这是正常的,因为应用程序(基于netty 3.6库)每小时打开和关闭很多tcp连接。我不认为我也应该担心这一点因为当前的类加载计数器没有增长。

我无法理解的是为什么大约每7天,总加载类的数量会下降到当前类加载的计数器。此外,堆内存使用情况似乎遵循相同的模式:堆空间增长到70mb,然后减少到20mb。

就像每7天执行更多“更深入”的垃圾收集器一样。

应用程序从未重新启动。

有人可以解释一下这种行为吗?感谢。

P.S。 不幸的是我无法截取JConsole的截图。

1 个答案:

答案 0 :(得分:3)

在Oracle JVM中,堆中有多个内存池。其中一个是旧的游泳池,另一个是烫发池。旧的gen池包含在几个垃圾收集中幸存下来的对象。 perm gen池包含加载的类和其他“永久”数据。

堆池的垃圾收集方式不同。您看到的标准垃圾收集通常在eden池上运行,而eden池是新创建的对象所在的位置。理论上说,如果你有很多短期对象,那么这些对象通常可以在一小堆中进行垃圾收集。与此同时,您的长寿命对象会被提升到较旧的池中,并且收集频率较低。

这一切都是为了允许更有效的垃圾收集,因为长寿命对象不像短期对象那样经常被考虑收集。因此,您所看到的“更深层次”执行可能是在收集旧的Gen池时。事实上,Oracle决定实施一些东西,以便perm gen池与旧的gen池同时收集垃圾,这就是为什么它们同时掉落的原因。

最后,简单地打开和关闭TCP连接不应该导致新类被加载。可能发生的是一些库在连接到达时创建新的动态代理。这个动态代理是一个在运行时创建的全新类,当它被创建时,它将增加你的总类加载次数。

参考文献:

In Java is Permanent Generation space garbage collected?

Java 6 garbage collection details(来自Oracle)