JVM实战01(CPU过高)

2020/12/07 Jvm

JVM实战01(CPU过高)

目录

问题简介

linux线上发生CPU过高情况,如何快速定位是什么原因导致?如何定位哪些热点代码?

一:top + jstack

1.使用top命令查出耗cpu的进程

1.键入:top命令

2.如上图:
    当前所有核数总的cpu平均是2.3us
    最耗cpu的进程是36032,耗费了30.7%(注意这里是进程消耗)

3.我们要定位热点代码光知道进程不行,还需要定位到该进程哪个线程消耗的多

2.使用top -Hp PID 查出线程的cpu消耗情况

1.键入:top -Hp 36032   //这里的36032是进程


2.如上图当前显示的是所有线程的cpu消耗:
    最耗cpu的线程是36044,耗费41.7%    

3.查线程的目的是为了搜索进程里的线程信息,精确到代码哪一行。

3.查找36044转成十六进制的值

1.键入: printf %x 36044
      输出:8ccc

2.jstack转存的信息是16进制的,所以我们要知道当前最耗的线程转成16进制线程号是多少,
  以便于搜索关键字,定位问题。

4.使用jstack查看进程(注意是进程,并且是16进制的)

1.键入:
      jstack 36032 > 1.txt   // 使用jstack将36032进程的所有信息转存到1.txt文件中(这里是进程级别的)

2.接着键入:
      cat 1.txt | grep -A 30 8CCC  //搜索8ccc这一行,以及往后30行

3. grep -A 命令
  -A -B -C 后面都跟阿拉伯数字
  -A是显示匹配后和它后面的n行。
  -B是显示匹配行和它前面的n行。
  -C是匹配行和它前后各n行。
  总体来说,-C覆盖面最大。用它保险些。哈哈。这3个开关都是关于匹配行的上下文的(context)

如上图:
    1.8ccc的线程名是"Thread-0"
    2.出问题的代码:
         HoldCPUTask.run(HoldCPUMain.java:13) 
         HoldCPUMain类的13行run方法,这里写了测试方法,方法里做了一个while死循环做大量计算,
         导致占用cpu过高。

二:JMC远程连接

1.如上图按步骤操作。

2.使用JMC有前提,远程linux机器开启了JMX配置。
  点击JMC上方:
              文件--->远程连接

三:常见引起cpu过高问题总结

1.无限while循环
  。尽量避免
  。无法避免,让循环执行慢一点

2.频繁GC
  。降低GC频率

3.频繁创建新对象
  。合理使用单例

4.序列化和反序列化
  。合理使用API
  。选择好用的类库

5.正则表达式(使用了一个引擎在进行字符串匹配的时候会进行回溯)
  。少用
  。改写正则表达式,降低回溯的发生
  
6.频繁的线程上下文切换
  。降低切换的频率

Search

    Table of Contents