java线程运行诊断:揪出占用cpu高的线程,定位问题代码---get新技能

程序占用cpu高达99.9%?

那么,怎么有效快速的定位是程序中的哪条线程出了问题,从而精确到具体是哪一行代码出了问题呢?

今天就来get一手新技能,是时候开始装逼了。
主要就针对windows系统和linux系统
首先介绍一个java命令:jstack
jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待着什么资源。

windows系统

首先看一段代码,先假装不知道问题出在哪里啊:

/**
 * 演示 cpu 占用过高
 */
public class Demo1_16 {
    public static void main(String[] args) {
        new Thread(null, () -> {
            System.out.println("1...");
            while(true) {

            }
        }, "thread1").start();
        new Thread(null, () -> {
            System.out.println("2...");
            try {
                Thread.sleep(1000000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread2").start();
        new Thread(null, () -> {
            System.out.println("3...");
            try {
                Thread.sleep(1000000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread3").start();
    }
}

运行后,发现也没有报错,但是cpu使用率就特别高,不用想,肯定代码出问题了。
解决办法:
1.打开任务管理器----->资源监视器
在这里插入图片描述
2.找到java进程对应的pid
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i4Yp4xtf-1578567481776)(DE2OQ==,size_16,color_FFFFFF,t_70)]
3.把java进程导出快照,也可不导出直接在窗口查看。直接win+R->cmd->运行命令

导出:jstack -l 13616 > c:/13616.stack
不导出:jstack -l 13616

这里是把java程序运行的信息导出到c盘的13616.stack的文件里。

4.在windows下只能查看进程的cpu占用率,要查看线程的cpu占用率要借助其他的工具,我这里用的是微软提供的 Process Explorer
下载地址http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

在这里插入图片描述
下载完,解压,运行procexp.exe,找到占cpu高的java程序,然后右键点击Properties...

在这里插入图片描述
5.然后选择 Threads 选项,找到占用cpu高的线程的tid,比如我这里是 7272的线程
在这里插入图片描述
6.把tid转换成16进制,我这里直接用系统自带的计算器转换,得到的线程tid的16进制的值为 1C68。置于为什么要转换呢,是因为先前用jstack导出的信息里面线程对应的tid是16进制的。
在这里插入图片描述
7.打开刚导出c盘的13616.stack文件,查找 1C68
在这里插入图片描述
8.重点来了,看问题到底出在哪里

在这里插入图片描述
老铁,get到没?
问题就在Demo1_16这个类中的第11行代码。

9.不信找源码,看看我说的结果对不对。
在这里插入图片描述
看到结果没,此处是不是应该有掌声了。问题找到了解决它就完了。

linux系统

Linux系统相对来说就简单很多了。
1.用top命令定位哪个进程对cpu的占用过高
在这里插入图片描述
如上图:PID为32655的java进程占用cpu高达99.3,这肯定是有问题的
2.用ps命令进一步定位是哪个线程引起的cpu占用过高

ps H -eo pid,tid,%cpu | grep 进程id

在这里插入图片描述
如上图:找到对应线程的tid为32665
3.输入命令:

jstack 进程id

在这里插入图片描述
可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号。

在这里插入图片描述
4.把上边查到的线程tid32665转成十六进制为7F99

在这里插入图片描述
5.查找问题到底出在哪里
在这里插入图片描述

发布了12 篇原创文章 · 获赞 22 · 访问量 2611

猜你喜欢

转载自blog.csdn.net/weixin_45240169/article/details/103806365