jstack、jmc、jhat工具使用詳解

jstack:html

在上一次【http://www.javashuo.com/article/p-yzmrwfpg-gw.html】jcmd中也能夠獲取線程的堆棧信息,回顧一下:java

其實在JDK中還有另外一個專門查看或導出Java應用程序中線程的堆棧信息jstack,具體瞅下它的使用:web

我們仍是以以前死鎖的MyTest3爲例試一下該工具:bootstrap

xiongweideMacBook-Pro:CoffeeMachineClient xiongwei$ jps -l
96336 org.gradle.launcher.daemon.bootstrap.GradleDaemon
94336 
98744 sun.tools.jps.Jps
17418 
98733 org.jetbrains.jps.cmdline.Launcher
96495 org.gradle.launcher.daemon.bootstrap.GradleDaemon
98734 com.jvm.memory.MyTest3
xiongweideMacBook-Pro:CoffeeMachineClient xiongwei$ jstack 98734
2019-04-12 16:32:16
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.92-b14 mixed mode):

"Attach Listener" #12 daemon prio=9 os_prio=31 tid=0x00007fb1d7882000 nid=0x4003 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #11 prio=5 os_prio=31 tid=0x00007fb1d81da800 nid=0x1703 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread-B" #10 prio=5 os_prio=31 tid=0x00007fb1d88a4000 nid=0x4703 waiting for monitor entry [0x0000700007a49000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.jvm.memory.A.method(MyTest3.java:17)
    - waiting to lock <0x00000007958c2f10> (a java.lang.Class for com.jvm.memory.A)
    at com.jvm.memory.B.method(MyTest3.java:35)
    - locked <0x0000000795a0fcb0> (a java.lang.Class for com.jvm.memory.B)
    at com.jvm.memory.MyTest3.lambda$main$1(MyTest3.java:10)
    at com.jvm.memory.MyTest3$$Lambda$2/1989780873.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

"Thread-A" #9 prio=5 os_prio=31 tid=0x00007fb1d7881000 nid=0x4803 waiting for monitor entry [0x0000700007946000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.jvm.memory.B.method(MyTest3.java:31)
    - waiting to lock <0x0000000795a0fcb0> (a java.lang.Class for com.jvm.memory.B)
    at com.jvm.memory.A.method(MyTest3.java:21)
    - locked <0x00000007958c2f10> (a java.lang.Class for com.jvm.memory.A)
    at com.jvm.memory.MyTest3.lambda$main$0(MyTest3.java:6)
    at com.jvm.memory.MyTest3$$Lambda$1/2093631819.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

"Service Thread" #8 daemon prio=9 os_prio=31 tid=0x00007fb1d8021000 nid=0x3b03 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007fb1d9033000 nid=0x3903 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007fb1d7828800 nid=0x3803 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007fb1d9000000 nid=0x3703 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fb1d7827000 nid=0x4b07 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fb1d800d800 nid=0x3003 in Object.wait() [0x0000700007231000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000795588ee0> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x0000000795588ee0> (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)

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fb1d800c800 nid=0x2f03 in Object.wait() [0x000070000712e000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000795586b50> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    - locked <0x0000000795586b50> (a java.lang.ref.Reference$Lock)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=31 tid=0x00007fb1d7815800 nid=0x5403 runnable 

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fb1d900d000 nid=0x2007 runnable 

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fb1d7801000 nid=0x1e03 runnable 

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fb1d7812000 nid=0x2a03 runnable 

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fb1d7812800 nid=0x2c03 runnable 

"VM Periodic Task Thread" os_prio=31 tid=0x00007fb1d7829800 nid=0x3d03 waiting on condition 

JNI global references: 309


Found one Java-level deadlock:
=============================
"Thread-B":
  waiting to lock monitor 0x00007fb1d90230b8 (object 0x00000007958c2f10, a java.lang.Class),
  which is held by "Thread-A"
"Thread-A":
  waiting to lock monitor 0x00007fb1d90259f8 (object 0x0000000795a0fcb0, a java.lang.Class),
  which is held by "Thread-B"

Java stack information for the threads listed above:
===================================================
"Thread-B":
    at com.jvm.memory.A.method(MyTest3.java:17)
    - waiting to lock <0x00000007958c2f10> (a java.lang.Class for com.jvm.memory.A)
    at com.jvm.memory.B.method(MyTest3.java:35)
    - locked <0x0000000795a0fcb0> (a java.lang.Class for com.jvm.memory.B)
    at com.jvm.memory.MyTest3.lambda$main$1(MyTest3.java:10)
    at com.jvm.memory.MyTest3$$Lambda$2/1989780873.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
"Thread-A":
    at com.jvm.memory.B.method(MyTest3.java:31)
    - waiting to lock <0x0000000795a0fcb0> (a java.lang.Class for com.jvm.memory.B)
    at com.jvm.memory.A.method(MyTest3.java:21)
    - locked <0x00000007958c2f10> (a java.lang.Class for com.jvm.memory.A)
    at com.jvm.memory.MyTest3.lambda$main$0(MyTest3.java:6)
    at com.jvm.memory.MyTest3$$Lambda$1/2093631819.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

jmc:Java Mission Control(Java任務控制)瀏覽器

它也是一體化的可視化工具,相比jconsole或jvisualvm,它呈現的功能更多,並且還能夠在程序運行期會不斷實時的呈現變動的數據,下面瞅下它,仍是以MyTest程序來實驗:服務器

其中裏面提到了一個Java飛行記錄器:jvm

而在上一次【http://www.javashuo.com/article/p-yzmrwfpg-gw.html】中也提到了它:ide

JFR:Java Flight Recorder,它是能夠實時的獲取進程的統計數據。工具

我們簡單來使用一下它:學習

先來單擊瞅下"MBean服務器":

是否是看到如此華麗的界面眼前一亮,並且仍是實時跟蹤的,確實是夠強大,繼續大體看一下:

其中上面出了一個元空間:

至關於將jcmd集成到這個工具裏面了,接下來看一下飛行記錄器:

個人天呀,比以前看到的界面還豐富好看,真的好強大,隨便瞅一瞅其它的:

能夠看到它裏面還有不少功能切換:

另外對於JFR是能夠用jcmd命令生成出飛行記錄器的記錄文件的,以下:

這裏咱們運行以前元空間的示例來用此工具來觀察一下:

並且使用量會時時的進行變化:

也能夠看到最大的元空間是200MB,正是咱們在JVM上設置的大小參數:

而後當元空間溢出以後,則能夠在jmc工具給出了一個斷開提示:

關於該工具也只是作了一些基本的學習,具體在實際中的使用還得本身來實踐,仍是至關之強大的。

jhat:能夠用來分析堆轉儲文件

這裏得用以前的這個程序來演示了:

該程序會致使堆內存溢出,同時咱們在JVM中設置了這樣的參數:

運行,來看當堆內存溢出時生成的轉儲文件:

咱們知道能夠用jvisualvm可視化的工具來分析,那若是可視化的工具在實際場景中用不了怎麼辦呢?此時jhat就能夠發揮做用了,我們用它來分析一下該轉儲文件:

因此我們能夠用瀏覽器訪問一下:

其中重點看一下咱們的MyTest1,點擊查看細節:

其中還能夠看到也有OQL:

這裏我們簡單的使用一下,先來感覺下,具體詳細的用法待以後有須要再現查,好比咱們想查詢當前是ClassLoader子類的名字,OQL能夠這樣寫:

而咱們在jvisualvm可視化的工具中也有OQL的查詢,我們在它裏面來試一下:

至此,關於JDK的一些關鍵工具的使用就暫且學習到這了,在將來的JVM學習中這些工具是會派上用場的,這些工具的使用是比較簡單的,可是若是不過一遍你都不知道有這些工具的存在,實際工做中其實就是怕有現成的東東能夠解決某個實際問題,可是因爲知識的侷限性徹底不知道有這麼個東東,那。。是否是會很痛苦。

相關文章
相關標籤/搜索