我的任务是调整一个生产应用程序,该应用程序包含一个Spring MVC REST接口,用于从内存缓存后端的Gemfire中提供大型(〜0mb - 100mb)json文档。该应用程序在JDK 1.6上的Tomcat 7内的CentOS服务器上运行。我们意识到应用程序需要调整,因为我们看到频繁停止世界旧代垃圾收集,如果无人看管,最终会导致java.lang.OutOfMemoryError: GC overhead limit exceeded
错误。
通过一些试验和错误以及监控,我设法使用以下参数调整应用程序:
-Xms20g
-Xmx20g
-XX:PermSize=256m
-XX:MaxPermSize=256m
-XX:NewSize=8g
-XX:MaxNewSize=8g
-XX:SurvivorRatio=8
-XX:+DisableExplicitGC
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:CMSInitiatingOccupancyFraction=70
我现在看到的垃圾收集行为(在大量测试负载下48小时)是伊甸园空间收集大约每10秒发生一次并持续约0.04秒。 48小时后,老一代人根本没有增长,而且那个地区有0个收藏品。
我的问题是,我是否应该关注不收集旧代垃圾?总的来说,这看起来像一个健康的调整?
修改: 对于关心我的GC日志的人,可以在http://filebin.ca/2U8awo1KTS1D/udf-gc.log.0
获取答案 0 :(得分:3)
我的问题是,我是否应该关注不收集旧代垃圾?
日志看起来很好。鉴于趋势,老一代的入住率增长非常缓慢。因此,它需要几天时间才能完全启动,以便启动并发标记周期。
好像你给它的内存要多得多。总的来说,这看起来像一个健康的调整?
老一代的入住率约为2G / 12G。这意味着您可能会将其缩小到4G,并且在并发周期开始之前仍需要几个小时
在年轻一代中,大多数年轻人只活到1岁(15岁)。这意味着年轻一代也可以在没有过多增加对象促销的情况下缩小
-XX:CMSInitiatingOccupancyFraction=70
应该与XX:+UseCMSInitiatingOccupancyOnly
答案 1 :(得分:0)
调整垃圾收集对于通用性能调优没有什么不同 - 在没有任何要求的情况下(至少对于非平凡的应用程序)有效地持续改进。在某些时候,改进对于实际使用案例不再重要。这就是你应该实现目标的原因。
关于GC的目标应该来自通用性能要求。这些反过来通常描述三个维度
满足这些要求后,您可以开始构建/推导它们,并在必要时进一步优化。我所隶属的公司最近发布了一本关于GC调整的相当全面的手册,因此您可以从手册的GC tuning sections查看更多内容。