公司内部的一个产品 (java 开发的) 运行在 window 虚拟机上,运行一段时间后CPU飙升,然后想查看是哪个线程占用。 折腾了一下午,终于定位到该线程。
下面我们通过两种方式定位到占用cpu比较高的线程。
public class ThreadCpuTest {
public static void main(String[] args) {
Thread busyTask = new Thread(() -> {
for (;;) {
double a = new Random().nextDouble();
double b = new Random().nextDouble();
double c = a * b;
}
});
busyTask.setName("busy task");
busyTask.start();
Thread lazyTask = new Thread(() -> {
for (;;) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
});
busyTask.setName("lazy task");
lazyTask.start();
}
}
运行该示例,然后使用监控工具定位到那个线程CPU使用率高。
通过 jps 可以查看到 我们运行的程序的进程号为 “11964”
下面我们通过 Process Explorer 工具进行查看 该进程中所有的线程。
如果你没有 Process Explorer ,点击下面连接,进行下载。 点击 https://docs.microsoft.com/zh-cn/sysinternals/downloads/process-explorer 地址下载 Process Explorer
打开Process Explorer 后,界面如下:
通过 jps 命令查看的进程号为 “11964”。然后在 Process Explorer中找到该进程。
选中 Threads 标签页。 发现线程ID为“20024” 的线程占用cpu比较高。
从线程的名字中,我们发现该线程的名字是“busy_task”。
然后就可以找到该线程,查看该线程是什么原因大量占用CPU,剩下的就是改程序的事情了
进程ID:“8880”
在左上部分找中,到Thread,选中 %Processor Time和 ID Thread 两个选项。 在左下部分中(选定对象的实例),找到所有“javaw”选中,点击添加按钮,然后显示如右半部分效果。
从图中发现线程ID为“10320”的线程,占用CPU比较高。
线程ID 转换成十六进制为“2850”
从线程堆栈信息中可以看出该线程为“busy_task”线程。