利用 kill -3 命令获取 Java 线程 dump 信息

本文将介绍怎样使用 kill -3 命令获取指定 Java 进程的线程堆栈信息。

什么是 kill -3?

kill -3 是一个 Unix/Linux 系统中的命令,用于向进程发送一个 SIGQUIT 信号。SIGQUIT 信号通常用于请求进程进行核心转储(dump core),以便进行调试和分析。

当你在终端中运行 kill -3 <进程ID> 时,会向指定进程发送 SIGQUIT 信号,进程会收到该信号并执行相应的操作。通常情况下,进程会生成一个核心转储文件,其中包含了进程在发生错误或异常时的内存和寄存器状态。这个核心转储文件可以用于后续的调试和分析。

注意:kill -3 命令只是向进程发送信号,具体的操作和响应取决于进程的实现。不同的进程可能对 SIGQUIT 信号有不同的处理方式,有些进程可能会忽略该信号,而有些进程可能会执行特定的操作。在使用 kill -3 命令时,请确保你有足够的权限来发送信号给指定的进程,并且谨慎使用,以免对系统和进程造成不可预料的影响。

获取 Java 线程 dump

第一步:通过 jps 命令获取 java 进程 PID,下面获取 tomcat 的进程 ID 如下:

hxstrive@localhost:~$ jps -lv | grep tomcat
23856 org.apache.catalina.startup.Bootstrap --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED 
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -Djava.util.logging.config.file=/home/hxstrive/tomcat-8.5.73/conf/logging.properties 
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= 
-Dcatalina.base=/home/hxstrive/tomcat-8.5.73 -Dcatalina.home=/home/hxstrive/tomcat-8.5.73 -Djava.io.tmpdir=/home/hxstrive/tomcat-8.5.73/temp

第二步:执行 kill -3 命令

hxstrive@localhost:~$ kill -3 23856

注意:

(1)如果项目通过 Tomcat 进行发布,即普通的 web 项目,则对应的堆栈信息会打印在 catalina.out 文件中。

(2)如果项目是基于 SpringBoot 并且使用 nohup java -jar xxx.jar & 命令运行,则 java 堆栈信息会在 jar 包所在的 nohup.out 文件中。

本文上面使用 kill -3 获取 tomcat 的堆栈信息,我们查看 catalina.out 看看吧,如下查看 catalian.out 最后 50 行:

hxstrive@localhost:~$ tail -n 50 tomcat-8.5.73/logs/catalina.out 
at java.lang.Thread.run(java.base@11.0.17/Thread.java:829)

"http-nio-8080-ClientPoller-1" #18 daemon prio=5 os_prio=0 cpu=47.29ms elapsed=295.22s tid=0x00007fb068608800 nid=0x5d49 runnable  [0x00007fb0411fa000]
   java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPoll.wait(java.base@11.0.17/Native Method)
at sun.nio.ch.EPollSelectorImpl.doSelect(java.base@11.0.17/EPollSelectorImpl.java:120)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@11.0.17/SelectorImpl.java:124)
- locked <0x00000000c4c3bcc0> (a sun.nio.ch.Util$2)
- locked <0x00000000c4c3bb60> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(java.base@11.0.17/SelectorImpl.java:136)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:871)
at java.lang.Thread.run(java.base@11.0.17/Thread.java:829)

"http-nio-8080-Acceptor-0" #19 daemon prio=5 os_prio=0 cpu=0.87ms elapsed=295.21s tid=0x00007fb06860b000 nid=0x5d4a runnable  [0x00007fb0410fa000]
   java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(java.base@11.0.17/Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(java.base@11.0.17/ServerSocketChannelImpl.java:533)
at sun.nio.ch.ServerSocketChannelImpl.accept(java.base@11.0.17/ServerSocketChannelImpl.java:285)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:514)
at java.lang.Thread.run(java.base@11.0.17/Thread.java:829)

"http-nio-8080-AsyncTimeout" #20 daemon prio=5 os_prio=0 cpu=32.80ms elapsed=295.21s tid=0x00007fb06860c800 nid=0x5d4b waiting on condition  [0x00007fb040ffa000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(java.base@11.0.17/Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1195)
at java.lang.Thread.run(java.base@11.0.17/Thread.java:829)

"VM Thread" os_prio=0 cpu=66.86ms elapsed=299.50s tid=0x00007fb0680b4800 nid=0x5d38 runnable  

"GC Thread#0" os_prio=0 cpu=104.57ms elapsed=299.62s tid=0x00007fb06802f000 nid=0x5d33 runnable  

"GC Thread#1" os_prio=0 cpu=107.66ms elapsed=298.74s tid=0x00007fb038009000 nid=0x5d43 runnable  

"G1 Main Marker" os_prio=0 cpu=3.18ms elapsed=299.61s tid=0x00007fb068049800 nid=0x5d34 runnable  

"G1 Conc#0" os_prio=0 cpu=0.18ms elapsed=299.61s tid=0x00007fb06804b800 nid=0x5d35 runnable  

"G1 Refine#0" os_prio=0 cpu=8.26ms elapsed=299.61s tid=0x00007fb068087000 nid=0x5d36 runnable  

"G1 Young RemSet Sampling" os_prio=0 cpu=86.67ms elapsed=299.61s tid=0x00007fb068088800 nid=0x5d37 runnable  
"VM Periodic Task Thread" os_prio=0 cpu=375.41ms elapsed=299.38s tid=0x00007fb068106800 nid=0x5d41 waiting on condition  

JNI global refs: 19, weak refs: 0

Heap
 garbage-first heap   total 87040K, used 10788K [0x00000000c3200000, 0x0000000100000000)
  region size 1024K, 8 young (8192K), 5 survivors (5120K)
 Metaspace       used 13772K, capacity 14420K, committed 14848K, reserved 1062912K
  class space    used 1422K, capacity 1685K, committed 1792K, reserved 1048576K
人生就像赛跑,不在乎你是否第一个到达终点,而在乎你有没有跑完全程。
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号