最近碰到多起java程序导致服务器cpu使用率100%的情况,下面把排查解决方法记录下来。

其实遇到这种情况,首先要保持冷静的头脑,遇事不乱。然后望闻问切,找到病根,直达病灶。所谓望闻问切就是,首先使用top找到最耗费cpu资源的进程找到,然后使用jstack, jmap等方式保存现场,然后使用top -Hp找到最好费cpu资源的线程ID,在按图索骥。同时我们也不要遗漏跟改进程有关的网络连接情况,和磁盘IO方片深入排查问题。

保存犯罪现场

第一步找到犯罪分子(Java进程ID),和最耗费cpu资源的线程ID

1) 使用top 找到最耗费资源的java进程号 9370

2)找到该进程的 线程总个数

ps -Lfp 9370 | wc -l

#(也可以使用ps -mp 9370 查看进程运行时间 或者 ps -Tp 进程情况)

有这么多线程难怪会这么耗费cpu。

3) 找到最耗费资源的线程

#可以找到最好费资源的线程号 9374

top -Hp 9370

4) 将最耗费资源线程id转换为十六进制

可以使用下面shell命令转化线程id为十六进制的。

#把线程转为十六进制

printf '%x\n'

9374 结果是 249e

使用jstack保存栈信息

保存栈信息,同时在栈信息中查找 0x249e

jstack -l 9370 > stack.info

grep **0x249e** stack.info -A 10

列出栈信息,同时确认

到此问题已经终结,找到了问题。

jmap备份堆信息

上个案例因为是GC配置问题导致了高cpu占用率, 但是有的时候排查问题需要栈和堆结合起来一起排查。下面我举一个例子

public class DeadLock{

public static void main(String[] args){

ResourceA resourceA = new ResourceA();

ResourceB resourceB = new ResourceB();

MyThreadA threadA = new MyThreadA(resourceA, resourceB );

MyThreadB threadB = new MyThreadB(resourceA, resourceB );

threadA.start();

threadB.start();

}

}

class MyThreadA extends Thread{

private ResourceA rA;

private ResourceB rB ;

private String threadName;

public MyThreadA(ResourceA resourceA, ResourceB resourceB){

this.rA = resourceA;

this.rB = resourceB;

}

@Override

public void run(){

threadName = Thread.currentThread().getName();

consumeResource();

}

public void consumeResource(){

synchronized (this.rA){

if(!this.rA.getResourceA().equals(threadName)){

this.rA.consumerA(threadName);

System.out.println(this.threadName + " 消费 A");

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (this.rB){

if(!this.rB.getResourceB().equals(threadName)){

this.rB.consumerB(threadName);

System.out.println(this.threadName + " 消费 B");

}

}

}

}

}

}

class MyThreadB extends Thread{

private ResourceA rA;

private ResourceB rB ;

private String threadName;

public MyThreadB(ResourceA resourceA, ResourceB resourceB){

this.rA = resourceA;

this.rB = resourceB;

}

@Override

public void run(){

threadName = Thread.currentThread().getName();

consumeResource();

}

public void consumeResource(){

synchronized (this.rB){

if(!this.rB.getResourceB().equals(threadName)){

this.rB.consumerB(threadName);

System.out.println(this.threadName + " 消费 B");

}

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (this.rA){

if(!this.rA.getResourceA().equals(threadName)){

this.rA.consumerA(threadName);

System.out.println(this.threadName + " 消费 A");

}

}

}

}

}

class ResourceA{

private String resourceA = "";

public String getResourceA(){

return resourceA;

}

public void consumerA(String name){

this.resourceA = name;

}

}

class ResourceB{

private String resourceB = "";

public String getResourceB(){

return resourceB;

}

public void consumerB(String name){

this.resourceB = name;

}

}

上面很明显是一个死锁的例子。我们就结合线程的栈去和堆区来进行深入排查。

jstack -l 2300 > stack.info

jmap -dump:format=b,file=jmap.info 2300

首先打开stack文件,发现Thread-1 在等待资源 0x76ab71990;同时锁住了资源0x76ab72ab0。但是Thread-0刚好相反。那么我们可以去堆文件中看下这两个资源到地址什么。而0x76ab72ab0和0x76ab71990分别代表了内存地址。

我们使用jhat解析heap文件,视图还原0x76ab72ab0和0x76ab71990两个资源

jhat -J-d64 -J-mx3g -port 34567 ~/Desktop/jmap.info

然后打开浏览器,输入localhost:34567,查找0x76ab72ab0和0x76ab71990我们甚至可以点击进入两个对象里面查看运行时的变量值。

而且jvm很智能的检测出有死锁现象发生,并且在堆文件中提示出来了

Found one Java-level deadlock:

=============================

"Thread-1":

waiting to lock monitor 0x00007fe2f000df58 (object 0x000000076ab71990, a ResourceA),

which is held by "Thread-0"

"Thread-0":

waiting to lock monitor 0x00007fe2f000b618 (object 0x000000076ab72ab0, a ResourceB),

which is held by "Thread-1"

Java stack information for the threads listed above:

===================================================

"Thread-1":

at MyThreadB.consumeResource(DeadLock.java:85)

- waiting to lock <0x000000076ab71990> (a ResourceA)

- locked <0x000000076ab72ab0> (a ResourceB)

at MyThreadB.run(DeadLock.java:67)

"Thread-0":

at MyThreadA.consumeResource(DeadLock.java:44)

- waiting to lock <0x000000076ab72ab0> (a ResourceB)

- locked <0x000000076ab71990> (a ResourceA)

at MyThreadA.run(DeadLock.java:27)

Found 1 deadlock.

到此排查工作到一段落了。下面还有专门篇章详细讲解stack和heap文件里面的奥妙。

java 分析jstack日志_望闻问切使用jstack和jmap剖析java进程各种疑难杂症相关推荐

  1. jstack 脚本 自动日志_深入理解jstack日志

    Tags : jstack日志发表时间: 2019-03-17 23:53:19 在分析线上问题时常使用到jstack 命令将当时Java应用程序的线程堆栈dump出来. 面对jstack 日志,我们 ...

  2. jstack调试_增压的jstack:如何以100mph的速度调试服务器

    jstack调试 使用jstack调试实时Java生产服务器的指南 jstack就像U2一样-从时间的黎明就一直在我们身边,我们似乎无法摆脱它 . 除了笑话,到目前为止,jstack是您的工具库中用于 ...

  3. java高并发日志_高并发下log4j的性能瓶颈

    开篇 近期由于业务需要进行业务迁移,期间因为误设置log4j的日志级别,导致系统性能整体下降,具体表现在QPS下降明显,系统RT上升.迁移期间由于各类系统环境较原来有较大差别,因为在排查过程中也走了一 ...

  4. java 打开gc日志_在运行时打开GC日志记录

    java 打开gc日志 总是有下一个JVM表现不佳. 而且,您内心深知,如果您只有少数启动选项可以公开一些有关正在发生的事情的信息,那么您可能就有机会真正修复该死的东西. 但是不,您需要的标志( -X ...

  5. python分析nginx日志_利用python分析nginx日志

    最近在学习python,写了个脚本分析nginx日志,练练手.写得比较粗糙,但基本功能可以实现. 脚本功能:查找出当天访问次数前十位的IP,并获取该IP来源,并将分析结果发送邮件到指定邮箱. 实现前两 ...

  6. java高深技术总结_一名25K以上的高薪Java程序员总结出的技术以及学习技能

    原标题:一名25K以上的高薪Java程序员总结出的技术以及学习技能 总所周知,Java是目前使用最为广泛的网络编程语言之一. 它具有简单,面向对象,稳定,与平台无关,解释型,多线程,动态等特点. 一般 ...

  7. 百度java的线程技术_自我提升(基础技术篇)——java线程简介

    前言:虽然自己平时都在用多线程,也能完成基本的工作需求,但总觉得,还是对线程没有一个系统的概念,所以,查阅了一些资料,理解那些大神和官方的资料,写这么一篇关于线程的文章 本来想废话一番,讲讲自己的经历 ...

  8. java职业发展路线图_从程序员到CTO的Java技术路线图 JAVA职业规划 JAVA职业发展路线图 系统后台框架图、前端工程师技能图 B2C电子商务基础系统架构解析...

    http://zz563143188.iteye.com/blog/1877266在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样 ...

  9. java se13安装教程_在Linux发行版中安装Java 13/OpenJDK 13的方法

    本文介绍在Linux发行版Ubuntu 18.04/16.04.Debian 10/9.CentOS 7/8.Fedora 31/30/29中安装Java 13/OpenJDK 13.Java SE ...

最新文章

  1. 让Transformer的推理速度提高4.5倍,这个小trick还能给你省十几万
  2. Android 系统Dimension和间距参数详解
  3. LinkedHashMap源码剖析
  4. Oracle中通过Job实现定时同步两个数据表之间的数据
  5. 如何使用bash / sed脚本删除文本文件的第一行?
  6. Java基础之数组合并,详细讲解
  7. Qt保存日志调试信息输出文件
  8. word论文格式调整
  9. 计算机网络谢希仁课后答案详解+计算机网络释疑与习题解答PDF+各章重点题目
  10. 图表数据分析怎么做,举实例给你说清楚
  11. C语言学习 单精度、双精度各有几位小数?
  12. excel宏设置之一键生成多张sheet并写入内容与格式
  13. 车道线分割项目记录-模型构建
  14. 【数据结构复习自用】树的性质
  15. Chrome插件与油猴脚本
  16. dreamware jquery 代码提示
  17. Workflow JBPM 工作流
  18. 硬盘数据丢失了怎么办
  19. iOS 10的iMessage新功能你都玩过了吗?炫酷技能大揭秘
  20. android 获取电量百分比 简书,使用手机不再纠结——隐藏电量百分比

热门文章

  1. SCLS:巴斯德所崔杰组揭示海洋无脊椎动物RNA病毒的遗传多样
  2. 23日晚西湖大学鞠峰报告:环境微生物宏基因组学
  3. QIIME 2教程. 11元数据Metadata(2020.11)
  4. R语言原生hist函数绘制直方图实战
  5. 密度聚类算法DBSCAN实战及可视化分析
  6. 集成学习VotingClassifier、HistGradientBoostingClassifier、Stacking、Blending
  7. 计算机一级在线模拟试题,计算机一级模拟试题带答案
  8. html5 游戏制作软件,制作h5小游戏的免费软件有哪些?
  9. 第二章 序列比对——Needleman-Wunsch全局比对
  10. 统计学:统计学概述(一)