我们有一个大型应用程序,分配的堆最小为2 GB,最大为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] 发布于 2011-06-26 22:59:25
看看你的日志,你最大的收集( 17秒)是收集老的(永久的)一代。在Sun JVM上使用并发垃圾收集器应该会有所帮助(+XX:UseConcMarkSweepGC),因为这将(主要)并发地执行收集,减少暂停时间)。
对于正在收集的数据量,您的年轻一代的停顿也相当大。你在什么规格的机器上运行?这些停顿也不是很频繁,所以如果您的目标是减少停顿时间,请尝试减少年轻一代(-XX:NewRatio)的大小,这应该会导致更短、更频繁的停顿。
您还应该确保您的机器上没有发生交换。你没有说你运行的是什么操作系统,但在Linux上运行:
vmstat 5在这些大型GC发生时,检查"si“和"so”列。如果它们不是零,要么减少机器上的内存使用量,要么调整"swappiness“可调参数。
发布于 2011-06-26 23:24:19
考虑使您的-Xms和-Xmx值相同。如果您愿意将堆的最大大小设置为8 8GB,那么也将其设为最小大小。这样,JVM就不必担心分配更多的内存。
完整GC的频率是多少?如果它们经常发生,那么您可能需要分析应用程序,而不是对最终无关紧要的gc参数进行调优。找出是什么在为您分配所有内存,并查看是否有减少它的方法。
发布于 2012-03-27 01:49:03
在JDK1.5和JDK1.6上,当您传递2到4 GB的堆内存时,您将看到GC暂停的增加。对需要更大数据堆的应用程序进行集群是一种选择。另一个我知道的是正在考虑替代JVM,如果你使用的是8 GB的堆,你可能会看到JDK 1.7的改进。有一些优化。此外,Sun / Oracle还需要考虑其他几种JVM。
如果您还没有读过这篇文章,那么这是一篇针对Java5.0/JDK1.5的非常强大的文章。这可能会有所帮助。Tuning Java 5.0。我将深入讨论更多细节,但上面的注释确实涵盖了一些元素。
或者,市场上还有另一种JVM,它来自一家名为Azul Systems的私人公司。他们有一些开源工具来检查他们的C4收集器是否能提供帮助。他们有一个JVM平台,可以在您的应用程序运行时并行运行。如果他们的JHiccup工具说您有GC问题,那么他们可以提供一个企业JVM。成本不是免费的,所以如果你正在寻找小型部署(一台服务器)和价值小于10,000美元的问题,那么我会(1)考虑替代免费的JVM和(2)尝试不同的JVM,如果你可以在它上运行(例如JDK 1.6 / 1.7)。如果这些都不是一个选项,请尝试集群,但是使用小于4 4GB的堆进行集群。
我在这里要说的唯一一点是,在选择JVM时有“多种”选项。JRocket确实对一些应用程序有帮助。
https://stackoverflow.com/questions/6484444
复制相似问题