Kill -3获取 java 线程转储

我使用 kill -3命令查看 Unix 中 JVM 的线程转储。但是在哪里可以找到这个 kill命令的输出呢?我迷路了! !

200138 次浏览

在放置 JVM 的 stdout 的同一位置。如果您有一个 Tomcat 服务器,这将是 catalina_(date).out文件。

线程转储被写入到执行 kill -3的 VM 之外的系统中。如果将 JVM 的控制台输出重定向到一个文件,则线程转储将位于该文件中。如果 JVM 在一个打开的控制台中运行,那么线程转储将显示在其控制台中。

您也可以选择使用 jstack (包含在 JDK 中)获取线程转储,并在任何需要的地方编写输出。在 unix 环境中不可用吗?

jstack PID > outfile

有一种方法可以将 JVM 线程转储在中断信号上的输出重定向到与 LogVMOutput 诊断选项分离的文件:

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log

在 Jboss 中,可以执行以下操作

nohup $JBOSS_HOME/bin/run.sh -c  yourinstancename $JBOSS_OPTS >> console-$(date +%Y%m%d).out  2>&1 < /dev/null &
kill -3 <java_pid>

这将把输出/threadump 重定向到上面命令中指定的文件控制台。

当使用 kill -3时,应该会在标准输出中看到线程转储。大多数应用程序服务器将标准输出写入单独的文件。当你使用 kill -3的时候,你应该可以在那里找到它。获得线程转储有多种方式:

  • kill -3 <PID>: 将输出转换为标准输出。
  • 如果可以访问服务器运行的控制台窗口,可以使用 Ctrl + Break组合键在 STDOUT 上生成堆栈跟踪。
  • 对于热点 VM,我们也可以使用 jstack命令来生成线程转储。这是 JDK 的一部分。语法如下:

    Usage:
    
    
    jstack [-l] <pid> (to connect to running process)
    jstack -F [-m] [-l] <pid>(to connect to a hung process)
    
    
    - For JRockit JVM we can use JRCMD command which comes with JDK Syntax:
    jrcmd <jrockit pid> [<command> [<arguments>]] [-l] [-f file] [-p] -h]
    
  1. 查找进程 ID [ PS ID ]
  2. 执行 jcmd [ PS ID ] Thread.print

随着 Java8的出现,jcmd是首选的方法。

jcmd <PID> Thread.print

以下是来自 Oracle 文档的片段:

JDK8的发布引入了 Java 任务控制、 Java 飞行记录器和用于诊断 JVM 和 Java 应用程序问题的 jcmd 实用程序。建议使用最新的实用程序 jcmd,而不是以前的 jstack 实用程序,以增强诊断并降低性能开销。

但是,随应用程序一起发布这个应用程序可能涉及许可问题,我不确定。

如果希望使用标准独立 Java 进程的线程转储,则应遵循的步骤

步骤1: 获取调用 Java 程序的 shell 脚本的进程 ID

linux$ ps -aef | grep "runABCD"


user1  **8535**  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh


user1 17796 17372   0 08:15:41 pts/49      0:00 grep runABCD

步骤2: 获取 runABCD 调用的子进程 ID。使用以上 PID 得到的孩子。

linux$ ps -aef | grep **8535**


user1  **8536**  8535   0   Mar 25 ?         126:38 /apps/java/jdk/sun4/SunOS5/1.6.0_16/bin/java -cp /home/user1/XYZServer


user1  8535  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh


user1 17977 17372   0 08:15:49 pts/49      0:00 grep 8535

步骤3: 获取特定进程的 JSTACK。获取 XYSServer 进程的 Process id

linux$ jstack **8536** > threadDump.log