【发布时间】:2016-01-20 15:54:21
【问题描述】:
我的任务是调整由 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
【问题讨论】:
-
您的所有对象都在移至旧代之前被收集,因此您不会遇到问题。唯一的问题是您的 Java 应用程序保留的大量内存永远不会被使用。
-
查看 JDK 中提供的 jstat 工具。找出Tenuring阈值以及Old Generation上升的速度(如果有的话)会很好。如果之前你有小的年轻代,那么很可能Tenuring Threshold 很小,并且许多临时对象被移动到老年代导致通常完整的gcs。
-
我不会担心“没有收集旧代垃圾”。老年代保持稳定就好了,这是你的App所需要的。
-
第一个:JVM 很古老,升级。第二:开启GC日志并提供日志。
-
@the8427 我确实启用了 GC 日志记录。如果您愿意查看日志,请告诉我,我会给您一个链接。