Jos*_*vio 30 java garbage-collection g1gc jboss7.x
我们在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之前是正常的,那时用户遇到了很大的滞后并开始抱怨.
Jos*_*son 31
Perm Gen增长的原因
对于那些不知道的人,这里有一个简单的方法来思考PremGen如何填满.Young Gen没有足够的时间让事情过期,因此他们被提升到Old Gen空间.Perm Gen拥有Young和Old Gen中对象的类.当收集Young或Old Gen中的对象并且不再引用该类时,它将从Perm Gen中"卸载".如果Young和Old Gen没有得到GC,那么Perm Gen也没有,一旦它填满它需要一个完全停止世界的GC.有关更多信息,请参阅介绍永久生成.
切换到CMS
我知道您正在使用G1,但如果您切换到并行标记扫描(CMS)低暂停收集器-XX:+UseConcMarkSweepGC,请尝试通过添加启用类卸载和永久生成集合-XX:+CMSClassUnloadingEnabled.
隐藏的Gotcha'
如果您使用的是JBoss,则RMI/DGC将gcInterval设置为1分钟.RMI子系统每分钟强制执行一次完整的垃圾回收.这反过来又促使促销,而不是让它被收集在年轻一代.
如果不是24小时,您应该将此更改为至少1小时,以便GC进行适当的收集.
-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
Run Code Online (Sandbox Code Playgroud)
每个JVM选项的列表
要查看所有选项,请从cmd行运行此选项.
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
Run Code Online (Sandbox Code Playgroud)
如果你想看看JBoss正在使用什么,那么你需要将以下内容添加到你的standalone.xml.您将获得每个JVM选项及其设置的列表.注意:它必须位于您要查看的JVM中才能使用它.如果你在外部运行它,你将看不到运行JBoss的JVM中发生了什么.
set "JAVA_OPTS= -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal %JAVA_OPTS%"
Run Code Online (Sandbox Code Playgroud)
当我们只对修改后的标志感兴趣时,可以使用快捷方式.
-XX:+PrintcommandLineFlags
Run Code Online (Sandbox Code Playgroud)
诊断
使用jmap确定哪些类正在消耗永久生成空间.输出将显示
总计
jmap -permstat JBOSS_PID >& permstat.out
Run Code Online (Sandbox Code Playgroud)这些设置对我有用,但取决于您的系统设置以及您的应用程序正在做什么将决定它们是否适合您.
-XX:SurvivorRatio=8 - 将幸存者空间比设置为1:8,从而产生更大的幸存者空间(比率越小,空间越大).与一个幸存者空间相比,SurvivorRatio是伊甸园空间的大小.较大的幸存者空间允许短寿命物体在年轻一代死亡的时间更长.
-XX:TargetSurvivorRatio=90 - 允许90%的幸存者空间被占用而不是默认的50%,从而更好地利用幸存者空间记忆.
-XX:MaxTenuringThreshold=31 - 防止从年轻人到老一代的过早晋升.允许短寿命物体在年轻一代死亡的时间更长(因此,避免晋升).此设置的结果是由于要复制的其他对象,次要GC时间会增加.可能需要调整此值和幸存者空间大小,以便平衡幸存者空间与将要长时间生活的终身对象之间的复制开销.CMS的默认设置是SurvivorRatio = 1024和MaxTenuringThreshold = 0,这会导致清除所有幸存者.这会对收集终身代的单个并发线程施加很大压力.注意:与-XX:+ UseBiasedLocking一起使用时,此设置应为15.
-XX:NewSize=768m - 允许指定初始年轻一代的尺寸
-XX:MaxNewSize=768m - 允许规定最大年轻代尺寸
这是一个更广泛的JVM选项列表.
| 归档时间: |
|
| 查看次数: |
14122 次 |
| 最近记录: |