JAVA 进程异常分析 - CPU、内存

现象:CPU跑满、内存快速增长、服务崩溃。

// 找到CPU高的进程pid
# top  

// 导出dump文件
# jstack -l <pid> > cpu.log

// 找出cpu高的线程tid
ps -mp <pid> -o THREAD,tid,time | sort -rn

// 转换线程tid
printf "%x\n" <tid>

// 在cpu.log中查找转换后的tid
  • 问题:C2 CompilerThread

原因和解释
定位到 C2 CompilerThread0这个线程占用了比较高的CPU。C2 Compiler 是JVM在server模式下字节码编译器,JVM启动的时候所有代码都处于解释执行模式,当某些代码被执行到一定阈值次数,这些代码(称为热点代码)就会被 C2 Compiler编译成机器码,编译成机器码后执行效率会得到大幅提升。
流量进来后,大部分代码成为热点代码,这个过程中C2 Compiler需要频繁占用CPU来运行,当大部分热点代码被编译成机器代码后,C2 Compiler就不再长期占用CPU了,这个过程也可以看作抖动。

解决方案
(1)最直接有效的方法是“预热(warm up)”:可以使用Jmeter等压测工具模拟线上访问流量,让C2 Compiler预先将热点代码编译成机器码, 减少对正式环境流量的影响。

(2) 设置JVM启动参数:-XX:CICompilerCount=threads
编译线程数,默认是2, 可以设置4或6。
在默认值下抖动时CPU已经满载,设置成更多的线程也不一定起作用,但对于CPU“高而不满”的情况会有用,能减少抖动时间。

(3) 排查接口调用次数
spring boot actuator
http://host:port/metrics
排查调用次数(counter)和时间(gauge)

参考:
http://www.xiuson.com/?p=203
https://cyberdak.github.io/jvm/2017/03/25/jvm-restart-cause-high-load
http://www.blogjava.net/xylz/archive/2012/03/15/371966.html

  • 问题:GC task thread
//查询内存垃圾回收
jstat -gcutil pid 2000 10
jmap -histo <pid>
jmap -dump:format=b,file=dumpFileName <pid> //所有的
jmap -dump:format=live,file=dumpFileName <pid> //活着的

一般是GC问题、内存不足或内存泄漏

使用MAT工具进行内存泄露分析
http://www.eclipse.org/mat/downloads.php

//-XX:+HeapDumpOnOutOfMemoryError将内存溢出时堆信息导出 
//-XX:HeapDumpPath=d:/a.dump指定堆信息导出的路径
-Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/a.dump -XX:+PrintGCDetails
  • 问题: Locked ownable synchronizers
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,758评论 3 83
  • 《深入理解Java虚拟机》笔记_第一遍 先取看完这本书(JVM)后必须掌握的部分。 第一部分 走近 Java 从传...
    xiaogmail阅读 5,204评论 1 34
  • 我们一起来讨论讨论java内存模型。理解内存模型对多线程编程无疑是有好处的。 java代码是如何跑起来的 java...
    caixiangwang阅读 622评论 0 3
  • java编译器,java解释器 1.java程序是一种可跨平台执行的语言,之所以可以跨平台,是因为jvm的存在,J...
    rabbit_coding阅读 7,040评论 2 18
  • 致永远的短毛 错过你的时候地上,留下了几根你的头发,惊惶失措,修长了睫毛,朱红的口红,似乎全部用心,全部灵验 今天...
    不像话的故事阅读 227评论 0 0