Java 8:即使指定了 CMSInitiatingOccupancyFraction,CMS 也不会为老年代启动

Java 8: CMS does not kick on for old generation even though CMSInitiatingOccupancyFraction specified

我正在 运行使用 tomcat7 和 JRE 1.8 创建 Java WebApp。该应用程序缓存大量数据(~15GB),并支持高吞吐量(~4K/秒)。由于高请求率,它在年轻代产生大量对象,部分对象在年轻代ParNew收集后存活下来,移动到幸存者,最终移动到堆内存中的老年代space。

这些对象不断积累在老年代。当老年代快满时,CMS 开始运行,这导致了 stop-the-world GC。这会影响我的应用程序的延迟。

为了避免这种情况,我开始使用 CMSInitiatingOccupancyFraction=85+UseCMSInitiatingOccupancyOnly。然而,尽管有这两个选项,当老年代已满 85% 时,CMS 不会启动。它仍然发生在老年代几乎满了并且进行 stop-the-world GC 时。我搜索了 CMSInitiatingOccupancyFraction 的限制,但找不到任何相关的 link 解释该行为。请在下面找到我的 tomcat 进程的确切命令行:

jsvc.exec -home /usr/lib/jvm/jre1.8.0_45 -user tomcat7 \
-pidfile /home/ameya/service/2.0.4-SNAPSHOT/logs/catalina-daemon.pid \
-outfile /home/ameya/service/2.0.4-SNAPSHOT/logs/catalina-daemon.out \
-errfile &1 \
-classpath /home/ameya/conf/service:/home/ameya/service/2.0.4-SNAPSHOT/bin/bootstrap.jar:/home/ameya/service/2.0.4-SNAPSHOT/bin/commons-daemon.jar:/home/ameya/service/2.0.4-SNAPSHOT/bin/tomcat-juli.jar \
-Djava.util.logging.config.file=/home/ameya/service/2.0.4-SNAPSHOT/conf/logging.properties \
-XX:+UseConcMarkSweepGC \
-XX:+CMSIncrementalMode \
-XX:+CMSIncrementalPacing \
-XX:+ExplicitGCInvokesConcurrent \
-Djava.awt.headless=true \
-XX:PermSize=1G \
-XX:MaxPermSize=5G \
-XX:+UseCMSInitiatingOccupancyOnly \
-XX:CMSInitiatingOccupancyFraction=85 \
-Xms12G -Xmx24G \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9004 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Duser.language=en \
-Duser.country=US \
-Dsun.net.inetaddr.ttl=30 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp/dump.tmp \
-XX:+AggressiveOpts \
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
-Djava.endorsed.dirs= \
-Dcatalina.base=/home/ameya/service/2.0.4-SNAPSHOT \
-Dcatalina.home=/home/ameya/service/2.0.4-SNAPSHOT \
-Djava.io.tmpdir=/home/ameya/service/2.0.4-SNAPSHOT/temp \
org.apache.catalina.startup.Bootstrap

有人可以帮我理解为什么 CMS 在老年代已满 85% 时不启动 运行 吗?

根据 oracle forums 增量 CMS 忽略 InitiatingOccupancyFraction。

iCMS 也在 openjdk 9 中 deprecated and will be removed。并且在服务器机器上没有多大意义,因为它主要用于 运行 在具有一个或两个内核的处理器上的应用程序。