结论:使用 g1 gc,jdk 11 相对于 jdk 8 来说性能明显下降。
3原因分析
=====
从 jdk 8 到 jdk 11, g1 gc 做了非常多的优化用于提高性能。为什么 jdk 11 对于应用者来说更不友好?简单的总结一下从 jdk 8 到 jdk 11 做得一些比较大的设计变化,如下表所示:
由于从 jdk 8 到 jdk 11 特性变化太多,对于这样的性能下降问题,为了能快速有效的解决,我们做了如下的尝试。
3.1统一 jdk 8 和 jdk 11 的参数,验证效果
=============================
由于 jdk 11 和 jdk 8 实现变化很多,部分功能完全不同,但是这些变化的功能一般都有参数控制,一种有效的尝试:梳理 jdk 8 和 jdk 11 关于 g1 的参数,将它们设置为相同的值,比如关闭 ihop 的自适应,关闭线程调整等。这里简单的给出 jdk 8 和 jdk 11 不同参数的比较,如下图所示:
将两者参数都设置为和 jdk 8 一样的值,重新验证测试,结果不变,jdk 11 性能仍然下降。
3.2gc日志分析,确定jdk 11性能下降点
=======================
对于 jdk 8 和 jdk 11 同时配置日志收集功能,重新测试,获得 gc 日志。通过 gc 日志分析,我们发现差异主要在 g1 young gc 的 object copy 阶段(耗时基本在这),jdk 11 的 young gc 耗时大概 200ms,jdk 8 的 young gc 耗时大概 100ms,两者设置的目标停顿时间都是 100ms。
jdk 11 中 gc 日志片段:
jdk 8中 gc 日志片段:
我们对整个日志做了统计,有以下发现:
并发标记时机不同,混合回收的时机也不同;
单次 gc 中对象复制的耗时不同,jdk 11 明显更长;
总体 gc 次数 jdk 11 得更多,包括了并发标记的停顿次数;
总体 gc 的耗时 jdk 11 更多。
发表评论