下面是使用以下参数运行的 JVM 的 jstat
输出
-Xmx10240m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode
jstat输出带有参数
jstat -gcutil <pid> 10s
该部分是 80 秒内的片段,据统计,其中将近 70 秒用于 GC。它们都是正在触发的 Full 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 空间收集的原因。
任何人都可以给我一些可能发生的事情的指示?
最佳答案
Why is the JVM doing so many garbage collections.
这很可能是因为永久代占用率相当高。使用 CMS 算法时,仅当老年代或永久代占用率超过定义的阈值时,才会启动主要收集。除非我记错了,否则老年代的默认占用阈值为 68%,这可以使用 -XX:CMSInitiatingOccupancyFraction=n
flag 更改。 .然而,在所提供数据的上下文中,这个值似乎并不重要,因为在进行统计时老年代的占用率似乎低于 25%(这并不意味着老年代在过渡期间没有填满,但当永久代本身表现出更高的占用率时,这是不太可能的)。
请注意,默认情况下,CMS 收集器不会从永久代中索取对象。这需要打开 CMSClassUnloading
旗帜。如果行为没有改善,那么很可能永久代的大小不正确,并且必须给它更多的内存,因为很明显永久代中只有很少的对象有资格收集每个主要的收集周期。
关于java - 为什么 JVM 会进行如此多的垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6647773/