本篇記錄下Java線程監控方法和Java線程堆棧信息分析
Java線程監控一:Jvisualvm
Jvisualvm是JDK自帶的圖形界面工具,監控之前需要先對jvm加監控參數。
使用步驟:
1、服務端對jvm加監控參數
一般來說,在tomcat的bin目錄下,catalina.sh文件中添加如下內容。文件保存修改后重啟tomcat。
JAVA_OPTS="-Dcom.sun.management.jmxremote.port=10086 - Dcom.sun.management.jmxremote.ssl=false - Dcom.sun.management.jmxremote.authenticate=false - Djava.rmi.server.hostname=10.0.0.9"
注意:
1)要根據實際情況修改port和hostname
2)添加好配置之后檢查端口是否被其他程序占用:netstat -lnp|grep 10086。如果執行完沒有結果,說明端口沒有被占用,可以使用
3)如果服務器上netstat未安裝的話,需要先安裝下:yum -y install net-tools
2、windowd端查看監控
1)找到java的bin目錄下jvisualvm.exe文件並雙擊打開如下:

2)選中“遠程”,右鍵“添加遠程主機”

3)在添加好的主機上右鍵,選中“添加JMX連接”

4)填寫上tomcat中配置的端口號,確定,JMX連接添加成功

5)添加成功如下:


Java線程監控二:jstack工具
jstack是Linux自帶的命令。執行的時候采集實時數據,相當於采集一個當時的快照。
命令:jstack pid(或者jstack pid > test.log)

Java線程堆棧信息分析
堆棧信息分析方法:
- 線程名稱:NioBlockingSelector.BlockPoller-1"
- 優先級:prio=5,默認是就是5
- tid=0x00007ff8111ef800:jvm線程id,jvm內部線程的唯一標識
- nid=0x1d48:對應系統線程id(NavtiwThread ID),和top命令查看的線程pid對應,不過一個是10進制,一個是16進制。(通過命令:top -H -p pid,可以查看該進程的所有線程信息)
- 線程狀態:java.lang.Thread.State: RUNNABLE
- 線程此時正在執行的方法,以及調用鏈:
at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:535) at java.net.ServerSocket.implAccept(ServerSocket.java:545) at java.net.ServerSocket.accept(ServerSocket.java:513) at org.apache.catalina.core.StandardServer.await(StandardServer.java:466) at org.apache.catalina.startup.Catalina.await(Catalina.java:776) at org.apache.catalina.startup.Catalina.start(Catalina.java:722) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:353) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493)
舉例:
1、使用top -H -p pid查看該進程的所有線程信息如下:

2、使用jstack命令:jstack pid > test.log,將test.log下載到windows機器上方便查看
3、將10進制的系統pid轉換成16進制,到test.log文件中查看該nid是否存在。(在線進制轉換地址:https://tool.lu/hexconvert/)
上圖中的線程pid有7468和7482,轉換成16進制分別為1d2c和1d3a,到test.log文件中搜索


從上圖看,兩個線程搜索成功,可以查看線程內容和調用鏈,方便后續性能瓶頸問題定位。
