问题是什么?
将实例升级到 Ubuntu 16.04 LTS 和 OpenJDK 8 后,经过数小时的正常运行后,GC 频率会突然增加几个数量级,最终使用不到 10% 的 HEAP。
我们分析了 GC 日志,除了频率增加外,没有发现任何异常。甚至 gceasy.io 也说一切正常。
它似乎不会对性能产生负面影响,但仍然是令人担忧的行为,Nagios/OP5 对此并不满意。分配率仅为 50mb/s,吞吐量和延迟是名义上的。
我们尝试废弃整个集群,从头开始安装所有内容,尝试了多种不同的 GC 和内存设置,但问题仍然存在。
以前有用过吗?
是的。在 Ubuntu 14.04 LTS、OpenJDK 7u151 上运行相同版本应用程序的其他实例按预期运行,频率和 HEAP 使用率正常。
问题
- 这就是 OpenJDK 8 的行为方式吗?
- 这是 Ubuntu 还是 OpenJDK 的问题?
- 使用 Xms 固定 HEAP 是我们唯一的选择吗?
- (这里到底发生了什么?)
实例
VM: AWS (4GB, 2 cores)
Ubuntu: Ubuntu 16.04.4 LTS
Kernel: 4.4.0-1060-aws
Java:
- OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11)
- OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
Tomcat 7.0.8x running with NIO connector and 150 threads
命令行(最新版本)
export CATALINA_OPTS="$CATALINA_OPTS -Xmx2048m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:NewRatio=1"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseParallelOldGC"
export CATALINA_OPTS="$CATALINA_OPTS -XX:ThreadStackSize=256k"
export CATALINA_OPTS="$CATALINA_OPTS -server"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Xloggc:/var/log/tomcat7/gc.log"
经过48小时性能测试
$ free
total used free shared buff/cache available
Mem: 3801048 1248348 1959488 5280 593212 2291640
Swap: 0 0 0
这是过去 24 小时性能测试的快照: - 05:30 HEAP 使用率突然下降,GC 增加 - 10:00 将负载增加 2 倍