为什么JVM会执行这么多垃圾收集

时间:2011-07-11 08:52:12

标签: java garbage-collection

以下是使用以下参数运行的JVM的jstat输出

-Xmx10240m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode 

jstat输出带参数

jstat -gcutil <pid> 10s

该部分是80秒的片段,根据统计数据,将近70秒用于GC。它们都是被触发的完整GC。

Timestamp   S0  S1  E       O       P       YGC     YGCT        FGC     FGCT        GCT         Diff
1040430.2   0   0   23.69   24.58   95.03   168048  22187.057   3672    4483.931    26670.988   8.175
1040440.2   0   0   0.1     24.58   95.02   168048  22187.057   3674    4495.551    26682.608   11.62
1040450.2   0   0   4.19    24.59   95.03   168048  22187.057   3677    4506.731    26693.788   11.18
1040460.2   0   0   0.01    24.45   95.02   168048  22187.057   3679    4517.391    26704.448   10.66
1040470.2   0   0   0.33    24.45   95.03   168048  22187.057   3681    4522.213    26709.27    4.822
1040480.2   0   0   0       24.43   95.02   168048  22187.057   3684    4534.816    26721.874   12.604

PermGen空间几乎已满,但我认为Sun GC机制不会尝试在这里收集,我可以看到基于Eden或Old空间收集的原因。

任何能够给我一些指示的人都可能会发生什么?

1 个答案:

答案 0 :(得分:3)

  

为什么JVM会进行如此多的垃圾收集。

这很可能是因为永久性发电占用率非常高。使用CMS算法时,只有当旧的或永久的世代占用率超过定义的阈值时,主要集合才会启动。除非我弄错了,否则老一代的默认占用率阈值为68%,可以使用-XX:CMSInitiatingOccupancyFraction=n flag进行更改。然而,在所提供的数据的背景下,这个值似乎并不重要,因为在统计数据采用时老一代的入住率似乎低于25%(这并不意味着老一代人没有在此期间填补但是,当永久性一代本身表现出更高的入住率时,它是不太可能的。)

请注意,CMS收集器默认情况下不会声明永久代的对象。这需要切换CMSClassUnloading标志。如果行为没有改善,则很可能永久代的大小不正确,并且必须给予更多的内存,因为很明显永久代中只有少数对象有资格收集。每个主要的收集周期。