首先能夠用jstack -l pid >sample.dump把java進程的運行棧dump出來。html
還能夠用grep java.lang.Thread.State sample.dump | awk '{print $2}' | sort -n | uniq -c 來看看進程中都有哪些線程狀態。java
2019-01-27 18:11:27 Full thread dump Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS mixed mode): Threads class SMR info: _java_thread_list=0x00007f8209356340, length=29, elements={ 0x00007f8268174000, 0x00007f8268178000, 0x00007f826818a800, 0x00007f826818c800, 0x00007f826818f000, 0x00007f8268191000, 0x00007f826820f800, 0x00007f8268223000, 0x00007f8268011000, 0x00007f820817e000, 0x00007f8208180000, 0x00007f820830b800, 0x00007f8208409000, 0x00007f8208adc000, 0x00007f8208c08000, 0x00007f8208c48000, 0x00007f8208d24000, 0x00007f8208d25800, 0x00007f81c4466800, 0x00007f81c4469000, 0x00007f81c446a000, 0x00007f8208d0e800, 0x00007f81e001f800, 0x00007f81e0023000, 0x00007f821c040000, 0x00007f8238001800, 0x00007f820c1f2000, 0x00007f81d0004800, 0x00007f820928b000 } "Reference Handler" #2 daemon prio=10 os_prio=0 cpu=15.09ms elapsed=19776.82s tid=0x00007f8268174000 nid=0x3f89 java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.1/Native Method) at java.lang.ref.Reference.processPendingReferences(java.base@11.0.1/Reference.java:241) at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.1/Reference.java:213) Locked ownable synchronizers: - None ... ... "fsnotifier64" #29 prio=4 os_prio=0 cpu=0.55ms elapsed=19772.56s tid=0x00007f81c4466800 nid=0x3fac in java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.1/Native Method) - waiting on <0x00000000e3205e88> (a java.lang.ProcessImpl) at java.lang.Object.wait(java.base@11.0.1/Object.java:328) at java.lang.ProcessImpl.waitFor(java.base@11.0.1/ProcessImpl.java:495) - waiting to re-lock in wait() <0x00000000e3205e88> (a java.lang.ProcessImpl) at com.intellij.execution.process.ProcessWaitFor$1$1.run(ProcessWaitFor.java:52) at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:229) at com.intellij.execution.process.ProcessWaitFor$1.run(ProcessWaitFor.java:45) at java.util.concurrent.Executors$RunnableAdapter.call(java.base@11.0.1/Executors.java:515) at java.util.concurrent.FutureTask.run(java.base@11.0.1/FutureTask.java:264) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.1/ThreadPoolExecutor.java:1128) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.1/ThreadPoolExecutor.java:628) at java.lang.Thread.run(java.base@11.0.1/Thread.java:834) Locked ownable synchronizers: - <0x00000000e3205f78> (a java.util.concurrent.ThreadPoolExecutor$Worker)
首先第一行顯示的是dump的時間,第二行是虛擬機的一些信息,接着就是線程的list,包括每一個線程的tid。linux
緊接着就是最重要的線程棧了:jvm
"Reference Handler":是線程的名字spa
#2不知道是啥,估計是線程列表中的的第幾個線程?操作系統
daemon說明是守護線程線程
prio=10 os_prio=0 cpu=15.09ms elapsed=19776.82s 分別是線程jvm優先級,線程操做系統優先級,cpu運行時間,實際運行時間。日誌
tid, Java memory address of its internal Thread control structure.16進制的code
nid, native thread id. 每個nid對應於linux下的一個tid, 即lwp (light weight process, or thread).16進制的,轉到10進制後能夠用ps命令找到它。htm
waiting on condition [0x00007f8248f2b000] 以及另外一個線程的 Object.wait() [0x00007f81e41ac000] 線程運行到哪了,能夠理解爲線程pc計數器的位置。
而後就是線程的狀態。這個通常都是重點,能夠看下《學會查看jstack Dump 日誌》,或者網上搜下怎麼看jstack日誌中的線程狀態。
接着就是線程棧了,在線程棧中還會列出所之類的(以橫杆-打頭的)。
最後是Locked ownable synchronizers。
須要注意的是,一個java進程中,還有許多自帶的線程好比gc線程啥的,因此你的單線程java可能也會有好多個線程dump出來,關於自帶的內部線程,參見《JVM內部運行線程介紹》一文。