Java死锁排查和Java CPU 100% 排查的步骤整理

目录

简介

一、Java死锁排查

使用jconsole

使用Java Visual VM

二、Java CPU 100% 排查

三、压力测试使用jstack找到系统的代码性能问题

参考


 简介

本篇整理两个排查问题的简单技巧,一个是java死锁排查,这个一般在面试的时会问到,如果没有写多线程的话,实际中遇到的机会不多;第二个是java cpu 100%排查,这个实际的开发中,线的应用出现这个问题可能性比较大,所以这里简单总结介绍一下,对自己学习知识的一个整理,提高自己的解决问题能力。

一、Java死锁排查

通过标题我们就要思考三个问题:

  1. 什么是死锁?

  2. 为什么会出现死锁?

  3. 怎么排查代码中出现了死锁?

作为技术人员(工程师),在面对问题的时候,可能需要的能力是怎么去解决这个问题。但是在学习技术知识的时候,那就要多问为什么,一定要锻炼自己这方面的能力,这样才能更好的掌握知识。

解答

  1. 什么是死锁?

    死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。百度百科:死锁

死锁图示

注:进程和线程都可以发生死锁,只要满足死锁的条件!

  1. 为什么会出现死锁?

    从上面的概念中我们知道
    (1)必须是两个或者两个以上进程(线程)
    (2)必须有竞争资源

  2. 怎么排查代码中出现了死锁?【重点来了
    首先写一个死锁的代码,看例子:

 

/**
 * 
 * 使用jstack 排查死锁
 * @author dufyun
 *
 */public class JStackDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread(new DeadLockTest(true));//建立一个线程
        Thread t2 = new Thread(new DeadLockTest(false));//建立另一个线程
        t1.setName("thread-dufy-1");
        t2.setName("thread-dufy-2");
        t1.start();//启动一个线程
        t2.start();//启动另一个线程
    }
}

class DeadLockTest implements Runnable {
    public boolean falg;// 控制线程
    DeadLockTest(boolean falg) {
        this.falg = falg;
    }
    public void run() {
        /**
         * 如果falg的值为true则调用t1线程
         */
        if (falg) {
            while (true) {
                synchronized (Demo.o1) {
                    System.out.println("o1 " + Thread.currentThread().getName());
                    synchronized (Demo.o2) {
                        System.out.println("o2 " + Thread.currentThread().getName());
                    }
                }
            }
        }
        /**
         * 如果falg的值为false则调用t2线程
         */
        else {
            while (true) {
                synchronized (Demo.o2) {
                    System.out.println("o2 " + Thread.currentThread().getName()); 
                   synchronized (Demo.o1) {
                        System.out.println("o1 " + Thread.currentThread().getName());
                    }
                }
            }
        }
    }
}

class Demo {
    static Object o1 = new Object();
    static Object o2 = new Object();
}

上面这段代码执行后,就会出现死锁,那么排查的方法有如下:

使用 jps + jstack

第一:在windons命令窗口,使用 jps -l 【不会使用jps请自行查询资料】

jps -l 命令

第二:使用jstack -l 12316 【不会使用jstack请自行查询资料】
jstack

使用jconsole

在window打开 JConsole,JConsole是一个图形化的监控工具!

在windons命令窗口 ,输出 JConsole
这里写图片描述

这里写图片描述

使用Java Visual VM

在window打开 jvisualvm,jvisualvm是一个图形化的监控工具!

在windons命令窗口 ,输出 jvisualvm

Java Visual VM

死锁检测

二、Java CPU 100% 排查

这个如果在实际的应用开发中遇到,要怎么排查呢?

这里没有一步步的图示过程,只有一个简单的操作过程!有空写一个详细的例子。

1 、 使用top命令查看cpu占用资源较高的PID
top命令
2、 通过jps 找到当前用户下的java程序PID

执行 jps -l 能够打印出所有的应用的PID,找到有一个PID和这个cpu使用100%一样的ID!!就知道是哪一个服务了。

3、 使用 pidstat -p

这里写图片描述

4 、 找到cpu占用较高的线程TID

通过上图发现是 3467的TID占用cup较大

5、 将TID转换为十六进制的表示方式

将3467转为十六进制 d8d,注意是小写!

巧转进制
6、 通过jstack -l

使用jstack 输出当前PID的线程dunp信息

7、 查找 TID对应的线程(输出的线程id为十六进制),找到对应的代码

查找

三、压力测试使用jstack找到系统的代码性能问题

1、在进行压力测试的时候,使用jps找到应用的PID
2、然后使用jstack输出出压力测试时候应用的dump信息
3、分析输出的日志文件中那个方法block线程占用最多,这里可能是性能有问题,找到对应的代码分析

 

参考

1、Java应用CPU占用100%原因分析(可点击,有链接)
2、[Java] CPU 100% 原因查找解决(可点击,有链接)
3、线上应用故障排查系列(可点击,有链接)
4、分析JAVA应用CPU占用过高的问题(可点击,有链接)

原文出处(可点击,有链接)


 


 

在linux环境下部署的应用,有时候出于各种原因,出现cpu占用100%的情况。这时候,就需要快速分析定位cpu占用的原因。

通常,通过linux系统的top命令,可以看出具体哪个进程占用了过多的cpu资源。但如果发现是java进程,那么就需要进一步分析是java进程中的具体哪个线程出现了问题。

1、确定Java应用进程编号
使用 jps 或 ps -ef|grep java 命令确定想要分析的应用的进程编号
jps

2、查看Java应用中线程CPU占比
使用top -p 101973 -H 命令查看指定进程下的线程cpu占用比例,分析是具体哪个线程占用率过高,其中 101973 就是通过第一步确定下来的进程编号

top

3、查看线程信息
从中选择占比较高的线程的编号(PID),并将该PID转换为16进制。通过jstack 101973 |grep -A 10 0x5bd8

å·ä½çº¿ç¨ä¿¡æ¯

通过该命令可以分析出线程的具体信息,再通过相应的解决方法来解决cpu占用过高的问题。

附:巧转进制
PID的进制转换可以使用程序员计算器,这里也提供另外一个的方法:通过chrome浏览器的JavaScript调试控制台进行转换。

在chrome浏览器中按F12打开开发者工具,切换至Console,定义一个变量a,再通过a的字符串转换函数转换至16进制。

è¿éåå¾çæè¿°

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值