我正在观察频繁的GC,包括我的java应用程序中的Full GC,在100个客户端进行负载关闭,进行Web服务调用,返回一个21KB(压缩大小)的JSON到客户端。未压缩的JSON大约为200 KB。由于频繁的GC,我观察到2.6秒的巨大延迟。这里是用于负载测试的JVM选项
-Xloggc:/mnt/apache-tomcat-7.0.29/logs/gc.log -XX:+UseConcMarkSweepGC -XX:+UseCompressedOops -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintTenuringDistribution -XX:+UseParNewGC -Xms5048M -XX:MaxTenuringThreshold=2 -XX:SoftRefLRUPolicyMSPerMB=73 -Djava.net.preferIPv4Stack=true -server -XX:NewRatio=4 -XX:SurvivorRatio=8
我正在使用带有4vCPU和15 MB RAM的AWS xLarge实例。
以下是流程生成的GCl日志
249.988: [GC 249.988: [ParNew
2163 Desired survivor size 52920320 bytes, new threshold 1 (max 2)
2164 - age 1: 83821968 bytes, 83821968 total
2165 - age 2: 20181408 bytes, 104003376 total
2166 : 896337K->103360K(930432K), 0.0409860 secs] 4453729K->3663260K(5065792K), 0.0412220 secs] [Times: user=0.16 sys=0.00, real=0.04 secs]
2167 250.051: [GC 250.051: [ParNew
2168 Desired survivor size 52920320 bytes, new threshold 2 (max 2)
2169 - age 1: 24997144 bytes, 24997144 total
2170 : 185613K->82956K(930432K), 0.0620620 secs] 3745513K->3744426K(5065792K), 0.0622810 secs] [Times: user=0.22 sys=0.00, real=0.06 secs]
2171 250.408: [GC 250.409: [ParNew
2172 Desired survivor size 52920320 bytes, new threshold 1 (max 2)
2173 - age 1: 86010184 bytes, 86010184 total
2174 - age 2: 19119656 bytes, 105129840 total
2183 : 930432K->103360K(930432K), 0.0904080 secs] 4767408K->4080180K(5065792K), 0.0906520 secs] [Times: user=0.33 sys=0.01, real=0.09 secs]
2184 251.229: [GC 251.229: [ParNew: 215470K->215470K(930432K), 0.0000370 secs] 4192291K->4192291K(5065792K), 0.0001620 secs] [Times: user=0.00 sys=0.00, real =0.00 secs]
2185 GC locker: Trying a full collection because scavenge failed
2186 251.229: [Full GC 251.229: [CMS251.495: [CMS-concurrent-mark: 6.443/8.877 secs] [Times: user=30.14 sys=3.55, real=8.87 secs]
2187 (concurrent mode failure): 3976820K->354739K(4135360K), 0.9792960 secs] 4192291K->354739K(5065792K), [CMS Perm : 42722K->42722K(71212K)], 0.9794580 sec s] [Times: user=0.96 sys=0.02, real=0.98 secs]
2188 252.439: [GC 252.440: [ParNew
2189 Desired survivor size 52920320 bytes, new threshold 1 (max 2)
2190 - age 1: 105807496 bytes, 105807496 total
2191 : 837144K->103360K(930432K), 0.0562310 secs] 1191884K->474282K(5065792K), 0.0564520 secs] [Times: user=0.22 sys=0.00, real=0.05 secs]
2192 252.676: [GC 252.676: [ParNew
2193 Desired survivor size 52920320 bytes, new threshold 1 (max 2)
2194 - age 1: 95836672 bytes, 95836672 total
2195 : 924377K->103360K(930432K), 0.0772210 secs] 1295299K->575312K(5065792K), 0.0774650 secs] [Times: user=0.28 sys=0.01, real=0.08 secs]
2196 253.001: [GC 253.001: [ParNew
2197 Desired survivor size 52920320 bytes, new threshold 1 (max 2)
2198 - age 1: 99903544 bytes, 99903544 total
2199 : 930432K->103360K(930432K), 0.0712130 secs] 1405673K->680963K(5065792K), 0.0714420 secs] [Times: user=0.25 sys=0.01, real=0.07 secs]
2200 253.324: [GC 253.324: [ParNew
2201 Desired survivor size 52920320 bytes, new threshold 1 (max 2)
2202 - age 1: 105814880 bytes, 105814880 total
2203 : 930432K->103360K(930432K), 0.0736730 secs] 1513770K->807662K(5065792K), 0.0739490 secs] [Times: user=0.27 sys=0.00, real=0.08 secs]
2204 253.666: [GC 253.667: [ParNew
答案 0 :(得分:3)
我想知道为什么驾驶员只是简单地喋喋不休地说这个问题而不至于暂停评论为什么他们会这样做......这让我感到困扰。
关注此消息:
GC locker: Trying a full collection because scavenge failed
我找到了这个帖子:
https://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs
有了这些信息:
CMS也可以在增量模式(i-cms)下运行,启用 -XX:+ CMSIncrementalMode
您是否在(i-cms)模式下运行CMS?它似乎对我有帮助,但我承认这不是我的专业知识。刚刚停下来帮忙。
这里将进一步讨论这个问题和可能的解决方案:
https://forums.oracle.com/thread/1543499
此外,关注消息“并发模式失败”,这是一个主要问题: How to reduce java concurrent mode failure and excessive gc
答案 1 :(得分:2)
让我们总结一下你的记忆设置:
我认为提到的15 MB是一个错字。假设您的机器的RAM小于19.7 GB,选项“-Xms5048M”有效地将最小和最大堆大小设置为5048 MB(默认最大值为机器RAM的25%,因此如果您具有>则最大值将更高。 19.7 GB RAM)。
与选项-XX:NewRatio = 4和-XX:SurvivorRatio = 8一起使用的是以下内存布局:
现在让我们检查一下JVM的用途:
从您的日志中,您可以看到幸存者空间非常小;例如,在第2174行,年龄1和2条目的总和是182MB,因此到目前为止超过了S0 / S1大小。低最大年龄(1代或2代)也是幸存者空间太有限的标志 - JVM将减少最大年龄,因为它试图将幸存者空间利用率削减到目标值(默认为50%)。
第2183行的报告行表明从年轻到终身空间提升了136.5 MB(GC之后的年轻gen diff为930432 KB - 103360 KB = 827072 KB,总堆差异为4767408 KB - 4080180 KB = 687228 KB,因此推广139844 KB)。
在同一行2183上,您可以看到旧的gen用法是4080180 KB - 103360 KB = 3976820 KB = 3883.6 MB。这样只留下了154.8 MB的最大旧版本。
我不了解GC算法触发器的细节(从我学到的,它们确实在JVM版本之间进行了更改),但考虑到
......显然迫切需要Full GC。
作为解决方案,我会尝试增加年轻的基因大小
当然,增加总堆大小也会有所帮助,因为可以进一步调整SurvivorRatio值;特别是后者是高度依赖应用程序的,如果不深入了解应用程序和GC算法,我就不会触及它。