快速定位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