我们在JBoss 7应用服务器上运行了一个相当大的应用程序.在过去,我们使用的是ParallelGC,但它在一些堆大(5 GB或更多)并且通常几乎填满的服务器中给我们带来麻烦,我们会经常得到非常长的GC暂停.
最近,我们对应用程序的内存使用情况进行了改进,并且在少数情况下为应用程序运行的某些服务器添加了更多RAM,但我们也开始切换到G1,希望使这些暂停不那么频繁和/或更短.事情似乎有所改善,但我们看到一种奇怪的行为,以前没有发生过(使用ParallelGC):Perm Gen似乎很快就会填满,一旦达到最大值就会触发Full GC,这通常会导致长时间停顿在应用程序线程中(在某些情况下,超过1分钟).
我们使用512 MB的最大烫发尺寸几个月,在我们的分析中,使用ParallelGC,烫发尺寸通常会在390 MB左右停止增长.然而,在我们切换到G1之后,上面的行为开始发生了.我尝试将最大烫发大小增加到1 GB甚至1.5 GB,但仍然发生了Full GCs(它们只是不那么频繁).
在此链接中,您可以看到我们正在使用的分析工具的一些屏幕截图(YourKit Java Profiler).请注意,当触发Full GC时,Eden和Old Gen有很多可用空间,但Perm大小最大.完整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)] [时间:用户= 10.16 sys = 0.59,实际= 23.64秒]
您可以在此处查看完整日志(从我们启动服务器的那一刻起,直到完整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之前是正常的,那时用户遇到了很大的滞后并开始抱怨.