快速定位JVM中消耗CPU最多的线程


从哪里看来的,忘记了!!!

在日常 Java 的开发中,性能调优肯定是很多人不能绕开的一个环节。而其中最简单,也是最基础的一个问题就是如何定位消耗 CPU 最多的线程。 

例子的代码具体如下

public class Test { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(100 * 1000); } catch (Exception e) { } } }).start(); } Thread thread = new Thread(new Runnable() { @Override public void run() { int i = 0; while (true) { i = (i++) / 100; } } }); thread.setName("busyness"); thread.start(); System.out.println("start..."); } }

这个例子里新创建了 11 个线程,其中 10 个线程没干什么事,主要是 sleep,另外有一个线程在循环里一直跑着,可以想象这个线程是这个进程里最耗 CPU 的线程了,那怎么把这个线程给抓出来呢?

首先我们可以通过top找到最消耗CPU的进程

通过以上这个结果,我们可以看到 cpu 最高的线程是 pid 为 15641的线程,占了CPU是100% ,

我们可以通过top -Hp <pid>来看这个进程里所有线程的 CPU 消耗情况,得到类似下面的数据。

可以看到 cpu 最高的线程是 pid 为 15661的线程,占了 99.3%:

 将15661转化为16进制:

[root@localhost ~]# printf "%x\n" 15661 3d2d

然后执行  jstack -l pid 这里的pid 是进程的pid 比如上面的15664 

[root@localhost ~]# jstack -l 15641
2018-07-21 19:46:27 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode): "Attach Listener" #20 daemon prio=9 os_prio=0 tid=0x00007f1cec001000 nid=0x3d60 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "DestroyJavaVM" #19 prio=5 os_prio=0 tid=0x00007f1d14008800 nid=0x3d1a waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "busyness" #18 prio=5 os_prio=0 tid=0x00007f1d1411f000 nid=0x3d2d runnable [0x00007f1d18530000] java.lang.Thread.State: RUNNABLE at com.java8.demo.Test$2.run(Test.java:26) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f1d140e2000 nid=0x3d21 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f1d140d7000 nid=0x3d20 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f1d140d5000 nid=0x3d1f waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f1d140d3800 nid=0x3d1e runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f1d140a0800 nid=0x3d1d in Object.wait() [0x00007f1d19540000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000e4a08ec8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x00000000e4a08ec8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) Locked ownable synchronizers: - None "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f1d1409b800 nid=0x3d1c in Object.wait() [0x00007f1d19641000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000e4a06b68> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000e4a06b68> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) Locked ownable synchronizers: - None "VM Thread" os_prio=0 tid=0x00007f1d14094000 nid=0x3d1b runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f1d140e5000 nid=0x3d22 waiting on condition JNI global references: 9

上面的线程栈我们注意到 nid 的值其实就是线程 ID,它是十六进制的, 标识红色的nid编号就是我们要找的最终线程。

 

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM