2013-11-22 36 views
3

我正在研究Java应用程序中的性能问题。我们已经缩小到定期非常昂贵的垃圾收集。该应用程序做非常频繁的YoungGen垃圾收集(稍微多于每分钟一次),但通常小于0.5秒。然而,在某些情况下,我们会遇到一两个小时,其中收集时间高于20秒,在某些情况下高达160秒。分析gc日志,除了时间长的情况之外,在这些情况下似乎有所不同的是在内核模式(系统时间的大值)中花费的时间的很大一部分。垃圾收集的哪些部分需要系统时间?

什么原因导致在内核模式下花费时间?服务器运行Java 1.6.0_45,其中-Xms5704m -Xmx5704m-XX:+UseParallelOldGC

+0

你的问题是关于什么时候*一般*花费在内核模式?另外,您使用的是哪种JRE? – Chandranshu

+0

@Chandranshu:是的,GC期间系统时间很长的原因。我们正在运行Oracle JRE。 – carlpett

回答

1

有了这么大的堆,预计会有很长的Full GC。您可能会尝试使用并发标记和扫描,因为您的分配率似乎不太高(一分钟不多)。

看到 http://java-is-the-new-c.blogspot.de/2013/07/what-drives-full-gc-duration-its.html

和关于ConcMarkAndSweepGC: http://java-is-the-new-c.blogspot.de/2013/07/tuning-and-benchmarking-java-7s-garbage.html

对于这个问题,有什么需要SYS时间。在GC期间,可能会与内核和内核内存系统进行交互。

如果系统时间非常高,确保没有交换磁盘正在进行!由于GC需要周期性地迭代所有分配的对象,因此物理内存不足会导致java不能正常工作,因此如果内存区域被交换到磁盘,GC暂停可能会进入分钟。最好的是关闭交换。

0

这取决于你的旧有什么。并行GC不会是一个5GB堆的好候选者。如果你使用visualGC,你可能会拥有约1.5GB的年轻空间,约500mbsw的幸存者和约3.2GB的旧空间。

它需要时间来清除3.2 GB的内存。取决于您在应用中使用的长寿命对象的类型,这个时间可能会很长。使用可同时标记和清除的CMS收集器。这将有助于你的应用程序。如果可能的话,使用这些设置与CMS colelctor -XX:-UseAdaptiveSizePolicy -XX:+ UseTLAB -XX:ConcGCThreads = 12

这些shoudl给你一个很好的提升你的应用程序,虽然GC时代并不意味着现在作为停止世界清理会少一些。