2011-08-30 36 views
5

这就是GC如何充满详细GC启用貌似更大 -Java垃圾收集“真正”的时间比“用户” +“系统”

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] 

实时怎么能比用户这么多的大+ sys?

我的第一个想法是垃圾收集器正在等待资源,但这个资源似乎不是IO或CPU,因为当发生gc时,“top”输出不显示任何cpu或内存问题。

+0

如果它不在IO上等待并且它不受CPU限制,那么我唯一能想到的其他事情就是等待信号量/互斥量,或者真的非常慢地访问内存。 – Jonathan

+0

你在你的应用中使用JNI吗?你的堆的大小是多少,你有多少物理RAM? – Ron

+0

Xmx = 960 Mb,RAM = 4GB我们使用JNI但不是太频繁,JNI如何影响垃圾收集? –

回答

7

要完整收集,您需要停止所有线程。 (它叫停止世界收藏的原因之一)

停止所有线程可能需要很长时间,尤其是如果您拥有数千个线程。每个线程都必须达到“安全点”来停止它。

这种行为通常意味着你有太多的线程。您也可以考虑ConcurrenntMarkSweep收集器或不需要经常停止应用程序的新的G1收集器。

+2

这可能是一个线索。长GC发生在启用Yourkit代理的QA环境中。它可以防止线程达到安全点,因为我们之前有性能问题。 –

1

尝试阅读本文(更多链接包含在白皮书中):Java 1.5 GC Internals
我想大多数东西仍然适用于Java 1.6的虚拟机,它可以很好地了解GC的工作原理。
另外,请阅读:Tuning JVM's 1.6 Heap space
(也有另一个白皮书链接与说明性基准,但我只是无法找到它:(:(/
我会尝试,看看它是否弹出某处,但我想这是位于甲骨文网站的某个地方)

一般来说,不要太奇怪,试着尝试不同的选项,然后看看它是如何工作的,除非你有超过10%的性能增益,并且你的应用程序很关键。
原因很简单:在几个LOC中简单的代码重写可能会显着改变GC的行为。
花点时间尽情玩乐吧!:)