java线程运行诊断:揪出占用cpu高的线程,定位问题代码 您所在的位置:网站首页 java程序cpu占用过高怎么排查 java线程运行诊断:揪出占用cpu高的线程,定位问题代码

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

2024-07-14 03:29| 来源: 网络整理| 查看: 265

文章目录 windows系统linux系统 程序占用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

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.重点来了,看问题到底出在哪里

在这里插入图片描述

问题就在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.查找问题到底出在哪里 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有