1 问题
最近,在某个高QPS的服务在重启的时候,如图1.1所示,重启会load 非常高,出现尖刺,短信报警CPU使用率过高,然后一段时间负载就降下来。搜索下网络的文章,启动后高负载的原因大致是由于启动,随着代码的执行,jvm的jit编译器会将部分热点代码编译为目标机器代码,这时产生的编译线程会占用大量的cpu 导致系统负载高。但是通过top -H -p 查看编译线程的cpu 使用率,发现cpu 使用率比其他线程略高,但是没有明显差距,但是比较其他的请求线程,加在一起的cpu 使用率还是很可观。所以在此怀疑,JIT编译器需要代码执行一定的频率才会进行编译优化,系统刚启动的时候大部分的代码只是解释执行,解释执行的性能比编译执行的性能当然要差很多,所以系统的负载高,等到主要热点代码都是编译执行,系统负载就降下来。 那接下来如何对这个问题调优呢?

2 jvm 调优
针对上面的问题,有两个解决方案:
2.1 纯编译执行(-Xcomp)
jvm提供了一个参数-Xcomp ,这个参数可以使jvm运行在纯编译的模式,所有的方法在第一次调用的时候就会编成机器代码,但是现实的话,设置了这个参数之后系统启动负载的确没有上升,这验证了我们之前的猜测,但是随之而来的问题,启动的时间是原来的两倍多,这对我们的应用是不好接受的,现在我们应用启动时间都快到3分钟。所以纯编译不是我们的最优选择。不过,我们还有分层编译。
2.2 分层编译(-XX:+TieredCompilation)
除了纯编译和默认的mixed之外,jvm 从jdk6之后,引入了分层编译。HotSpot 内置两种编译器,分别是client启动时的c1编译器和

本文探讨了在高QPS服务重启时遇到的CPU负载问题,分析了JIT编译器在启动时的影响。通过实验,对比了纯编译执行和分层编译(-XX:+TieredCompilation)两种策略。纯编译虽然能避免启动时的性能问题,但会导致启动时间过长。分层编译则是一种折中方案,它在启动初期使用C1编译器快速编译代码,随后逐渐用C2编译器优化高频代码,实现在性能和启动时间间的平衡。在线上环境中,启用分层编译后,服务启动后的负载问题得到了显著改善。
最低0.47元/天 解锁文章
3343

被折叠的 条评论
为什么被折叠?



