【发布时间】:2013-11-28 20:31:43
【问题描述】:
我们有一个相当大的应用程序在 JBoss 7 应用服务器上运行。过去,我们使用 ParallelGC,但它在一些堆很大(5 GB 或更多)且通常几乎被填满的服务器上给我们带来了麻烦,我们会经常遇到很长的 GC 暂停。
最近,我们改进了应用程序的内存使用情况,并在少数情况下为运行应用程序的某些服务器添加了更多 RAM,但我们也开始切换到 G1 以希望减少这些暂停的频率和/或更短。情况似乎有所改善,但我们看到了一种以前没有发生过的奇怪行为(使用 ParallelGC):Perm Gen 似乎很快就被填满了,一旦达到最大值,就会触发 Full GC,这通常会导致长时间的停顿在应用程序线程中(在某些情况下,超过 1 分钟)。
几个月来,我们一直在使用 512 MB 的最大 perm 大小,在我们的分析期间,使用 ParallelGC 时,perm 大小通常会停止增长到 390 MB 左右。然而,在我们切换到 G1 之后,上述行为开始发生。我尝试将最大 perm 大小增加到 1 GB 甚至 1.5 GB,但仍然会发生 Full GC(它们只是不太频繁)。
在this link 中,您可以看到我们正在使用的分析工具(YourKit Java Profiler)的一些屏幕截图。请注意,当触发 Full GC 时,Eden 和 Old Gen 有很多可用空间,但 Perm 大小是最大的。在 Full GC 之后,Perm 的大小和加载的类的数量急剧减少,但它们又开始上升并重复循环。代码缓存很好,永远不会超过 38 MB(在这种情况下是 35 MB)。
下面是一段 GC 日志:
2013-11-28T11:15:57.774-0300: 64445.415: [完整 GC 2126M->670M(5120M), 23.6325510 秒] [伊甸园:4096.0K(234.0M)->0.0B(256.0M) 幸存者:22.0M->0.0B 堆:2126.1M(5120.0M)->670.6M(5120.0M)] [时间:user=10.16 sys=0.59, real=23.64 secs]
你可以看到完整的日志here(从我们启动服务器的那一刻起,直到完整的GC之后的几分钟)。
这里有一些环境信息:
java版本“1.7.0_45”
Java(TM) SE 运行时环境(内部版本 1.7.0_45-b18)
Java HotSpot(TM) 64 位服务器 VM(内部版本 24.45-b08,混合模式)
启动选项:-Xms5g -Xmx5g -Xss256k -XX:PermSize=1500M -XX:MaxPermSize=1500M -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintAdaptiveSizePolicy -Xloggc:gc.log
所以这是我的问题:
这是 G1 的预期行为吗?我在网上找到另一个帖子,有人质疑非常相似的事情,并说 G1 应该在 Perm Gen 上执行增量收集,但没有答案......
在我们的启动参数中有什么可以改进/纠正的吗?服务器有 8 GB 的 RAM,但我们似乎并不缺乏硬件,应用程序的性能很好,直到触发完整的 GC,那时用户会遇到很大的延迟并开始抱怨。
【问题讨论】:
-
这是其他人在非常相似的问题上寻求帮助的链接:mail.openjdk.java.net/pipermail/hotspot-gc-use/2013-October/…
-
我会尝试添加
-verbose:gc以查看更多详细信息,我也可以考虑尝试Chronon DVR。 -
我将添加该选项并让服务器运行一段时间以查看是否获得更多信息,但我很清楚导致完整 GC 运行的原因,我只是不'不明白这是否是 G1 的正确行为...
-
非常有趣的博文:mechanical-sympathy.blogspot.nl/2013/07/…,总而言之太长,但最后一段总结得很好:“如果延迟峰值是由 GC 引起的,那么投资调整 CMS 或 G1 以查看您的延迟目标是否达到目标可以满足。有时这可能是不可能的,因为高分配和提升率以及低延迟要求。GC 调整可以成为一项高技能的练习,通常需要更改应用程序以降低对象分配率或对象生命周期。"
-
Joshua Wilson 的帖子捕捉了 G1GC 与 CMS 的一些优点,但关于为什么会发生这种情况的问题的答案可能是在较早的电子邮件对话中,有趣的部分实际上从这里开始:mail.openjdk.java.net/pipermail/hotspot-gc-use/2010-July/…。他们讨论了某些区域可能永远不会被收集的可能性,因此会强制进行完整的 GC。在整个讨论过程中有一些非常有趣的提示,但不幸的是我在那里找不到明确的答案。也许您会根据自己的代码经验找到一些建议。
标签: java garbage-collection jboss7.x g1gc