性能监控之Java线程监控
本篇记录下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文件中搜索
从上图看,两个线程搜索成功,可以查看线程内容和调用链,方便后续性能瓶颈问题定位。