java获取cpu使用率_【问题记录】服务器启动CPU抖动过高

【问题记录】服务器启动CPU抖动过高

jdk安装

  1. jdk官网下载.jdk下载地址:https://www.oracle.com/java/technologies/
  2. 拷贝jdk文件到服务器.命令:scp [可选参数] file_source file_target eg:scp jdk-11.0.9_linux-x64_bin.tar.gz root@124.70.189.211:/frank
  3. 配置java环境.sudo vi /etc/profile使用vi编辑器填写java配置
export JAVA_HOME=/frank/jdk-11.0.9
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=./:JAVA_HOME/lib:$JRE_HOME/lib

source /etc/profile命令生效配置

  1. 查看安装成功java -version命令可以看到java版本信息打印

问题模拟排查

服务器开启两个界面,第一个界面执行命令top -H,查看cpu使用率.另一个界面执行java -jar xxx.jar命令,运行jar包.如下图所示:

1922b1cd0a74a5b70a56d14d9c9f1aae.png


在java代码运行的时候,发现一个cpu使用率很好的java进程,使用命令jstack -l pin打印线程情况如下图所示:

030d12e6007c54114392b0d8cd155566.png


我们发现C2 CompilerThreadC1 CompilerThread两个线程,长期持有了cpu,导致了cpu使用率的抖动.而且c2的使用时长远超C1.那么为什么C2 CompilerThread线程项目启动初期cpu使用率那么高,它在干什么呢?

Java程序在启动的时候所有代码的执行都处于解释执行模式,只有在运行了一段时间后,根据代码方法执行的次数,或代码里循环的执行次数等达到一定的阈值才会编译成机器码,编译成机器码后执行效率会得到大幅提升,而随着执行时间进一步拉长,JVM的各种更高级的编译优化手段就会逐渐加上,例如if条件的执行状况,逃逸分析等。这里的C2 CompilerThread线程干的就是编译优化的活。

在程序刚启动的时候,java还处于解释执行模式,因此服务效率很低,响应时间缓慢,处理得慢。而当流量持续不断导入时,我们代码的很多方法执行次数不断增多,此时C2 CompilerThread线程不断收集优化信息,并且开始将一些热点代码优化编译成本地机器码,因此该线程的cpu使用率增高。而当C2 CompilerThread线程完成初始编译优化过程后,C2 CompilerThread线程的cpu使用率开始下降,与此同时优化后服务的性能大幅提升,服务响应时间也大大缩短,服务的CPU也就下来了

现在的症结在于编译优化过程持续时间较长,引起抖动。如何降低编译优化的持续时间呢?

解决思路

  1. 预热
    如果在服务接受线上请求之前提前完成编译优化过程,那么将能避免此种抖动情况。一般的做法是预热,有两种方法:

1.1. 程序主动预热:在启动完成后,程序主动的访问热点的代码,确保主要的热点代码已被编译成机器码后再放入流量,可通过-XX:+PrintCompilation来确认。

1.2. 复制流量预热:通过tcpcopy软件拷贝一份线上nginx的流量进行预热,完成之后再导入线上流量。

  1. 启动多个线程进行编译优化:如果能加快编译优化速度,那也能降低解释执行阶段导致的抖动时间。因此可以多拿几个线程来做编译,加快达到高峰性能的速度。可以使用-XX:CICompilerCount参数来设置编译线程数目,这个值默认是2(图中也是2个),我们可以加到4(根据服务器情况配置).
  2. 采用多层编译:编译方式有三种:1、Client模式。2、Server模式。3、Tiered模式。我们服务默认是Server模式。
  • Server模式是采用c2高级编译的,会比较耗时且要运行一段时间才会触发编译。 Server模式的优点是编译后程序效率较高;
  • Client模式比较轻量也比较快触发(比Server模式触发快),编译优化后程序效率不如Server模式;
  • Tiered模式是Client模式和Server模式的折中,一开始会启用Client模式,可以在启动后更快的让部分代码先进入编译优化阶段,之后会启动Server模式,达到程序效率最大优化的目的。

Oracle JDK 7里的HotSpot VM已经开始有比较好的Tiered编译(tiered compilation)支持,可以设置参数-XX:+TieredCompilation来启动Tiered模式,java 8默认就是Tiered模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值