这就是使用详细gc启用的完整gc的样子 -
13463.547: [Full GC [PSYoungGen: 323053K->0K(325952K)]
[PSOldGen: 653170K->331738K(655360K)] 976224K->331738K(981312K)
[PSPermGen: 238715K->238715K(264448K)], 385.4631490 secs]
[Times: user=2.19 sys=1.35, real=385.50 secs]
实时如何比user + sys大得多?
我的第一个想法是垃圾收集器正在等待资源,但是这个资源似乎不是IO或CPU,因为“顶部”输出在gc发生时不会显示任何cpu或内存问题。
答案 0 :(得分:7)
要进行完整集合,您需要停止所有线程。 (它叫停止世界收藏的原因之一)
停止所有线程可能需要很长时间,尤其是如果你有成千上万的话。每个线程必须达到“安全点”才能阻止它。
这种行为通常意味着你有太多的线程。您也可以考虑使用ConcurrenntMarkSweep收集器或新的G1收集器,它不需要经常停止应用程序。
答案 1 :(得分:1)
尝试阅读此内容(白皮书中包含更多链接):Java 1.5 GC Internals。
我想大多数事情仍然适用于Java的1.6 VM,它提供了一个很好的洞察GC的工作方式
另请阅读:Tuning JVM's 1.6 Heap space
(还有另一个白皮书链接,带有说明性的基准,但我找不到它:(:/ /我会试着看看它是否会弹出某个地方,但我猜它位于Oracle网站的某处)< / p>
一般情况下,不要变得怪异。根据一些基本原理尝试并尝试不同的选项,看看它是如何工作的。除非你有一个&gt; 10%的性能提升和您的应用程序是至关重要的,尽量不要与很多细节混在一起。
原因很简单:只需几个LOC即可轻松改写代码,这可能会极大地改变GC的行为。
花些时间玩得开心! :)