我们有一个大型应用程序,分配堆数为2 GB min&最大8 GB在负载测试期间,我们发现一些非常长的暂停时间,GC周期大到16秒。最初我们使用的是“-XX:+ UseParNewGC”,但切换到UseParallelGC为我们提供了非常需要的性能提升,但我们在加载时确实存在更长的暂停时间问题。
我们尝试了很少的选择,例如增加年轻一代,但似乎没有什么可以帮助任何想法还有什么可以尝试?如果需要,我们可以自由增加堆大小,但我想知道可能会恶化gc暂停。如果无法做任何事情,我正在考虑使用具有5 GB堆而不是1个更大堆的群集应用服务器。 附上当前gc日志的快照
J
J Thu Jun 23 12:40:56 2011
J [GCJ
J Thu Jun 23 12:40:57 2011
[PSYoungGen: 2130792K->475247K(2084160K)] 7198716K->5543171K(7676608K), 1.3280110 secs] [Times: user=0.00 sys=1.88, real=1.33 secs]
J
J Thu Jun 23 12:41:00 2011
J [GCJ
J Thu Jun 23 12:41:01 2011
[PSYoungGen: 1966319K->417801K(1908928K)] 7034243K->5546416K(7501376K), 0.7025950 secs] [Times: user=0.01 sys=1.89, real=0.71 secs]
J
J Thu Jun 23 12:41:12 2011
J [GCJ
J Thu Jun 23 12:41:13 2011
[PSYoungGen: 1908873K->269608K(2155520K)] 7037488K->5523748K(7747968K), 1.3117340 secs] [Times: user=0.01 sys=1.44, real=1.31 secs]
J
J Thu Jun 23 12:41:33 2011
J [GC [PSYoungGen: 1747432K->138147K(1616000K)] 7001572K->5593865K(7208448K), 0.4949960 secs] [Times: user=0.01 sys=1.40, real=0.50 secs]
J [Full GCJ
J Thu Jun 23 12:41:50 2011
[PSYoungGen: 138147K->0K(1616000K)] [PSOldGen: 5455718K->3456287K(5592448K)] 5593865K->3456287K(7208448K) [PSPermGen: 256273K->256273K(524288K)], 17.0259440 secs] [Times: user=0.00 sys=16.88, real=17.02 secs]
J
J Thu Jun 23 12:42:09 2011
J [GC [PSYoungGen: 1477824K->85118K(2110848K)] 4934111K->3541406K(7703296K), 0.1437050 secs] [Times: user=0.00 sys=0.30, real=0.14 secs]
J
J Thu Jun 23 12:42:20 2011
J [GC [PSYoungGen: 1573438K->71812K(2100352K)] 5029726K->3600767K(7692800K), 0.2477960 secs] [Times: user=0.00 sys=0.65, real=0.25 secs]
答案 0 :(得分:3)
查看您的日志,您最大的收藏品(17秒)正在收集旧的(终身)一代。在Sun JVM上使用并发垃圾收集器应该有帮助(+ XX:UseConcMarkSweepGC),因为这将同时进行收集(主要是),减少暂停时间。
对于正在收集的数据量,您年轻一代的停顿也相当大。你在运行什么规格的机器?这些暂停也不是很频繁,所以如果你的目标是较短的暂停时间,请尝试减小年轻代的大小(-XX:NewRatio),这应该会导致更短,更频繁的暂停。
您还应确保您的计算机上没有发生交换。你没有说你正在运行什么操作系统,但是在Linux上运行:
vmstat 5
并在这些大型GC发生时检查“si”和“so”列。如果它们不为零,则要么减少机器上的内存使用量,要么调整“swappiness”可调参数。
答案 1 :(得分:0)
考虑使-Xms和-Xmx值相同。如果你愿意给堆最大8GB的大小,那么也要把它作为min。这样JVM就不必担心分配更多内存了。
完整的GC有多频繁?如果它们经常出现,那么您可能需要对应用程序进行概要分析,而不是在调整最终无关紧要的gc参数。找出为你分配所有内存的内容,看看是否有办法减少它。
答案 2 :(得分:0)
在JDK 1.5和JDK 1.6上,当您传递2到4 GB堆内存时,会看到GC暂停增加。需要更大数据堆的群集应用程序是一种选择。我知道的另一个是考虑替代JVM。如果您的堆容量为8 GB,则可能会看到JDK 1.7的改进。有一些优化。此外,Sun / Oracle还有其他几个JVM需要考虑。
如果你还没有读过这篇文章,那么对于Java 5.0 / JDK 1.5来说,它是一个非常强大的文章。它可能有所帮助。 Tuning Java 5.0。我会详细介绍,但上面的评论确实涵盖了一些元素。
另外,市场上还有一个来自一家名为Azul Systems的私人公司的JVM。他们有一些开源工具来检查他们的C4收集器是否可以提供帮助。他们有一个JVM平台,可以在您的应用程序运行时并行运行。如果他们的JHiccup工具说您有GC问题,那么他们可以提供企业JVM。成本不是免费的,所以如果您正在寻找小型部署(一台服务器)和价值低于10,000美元的问题,那么我会(1)考虑备用免费JVM和(2)尝试不同的JVM(如果您可以运行它) (例如JDK 1.6 / 1.7)。如果这些都不是一个选项,请尝试群集,但使用低于4GB的堆。
我在这里唯一指出的是选择JVM时有“ARE”选项。 JRocket确实可以帮助一些应用程序。