kill-3获取java线程转储

kill-3获取java线程转储,java,multithreading,dump,Java,Multithreading,Dump,我正在使用kill-3命令查看unix中JVM的线程转储。但是在哪里可以找到这个kill命令的输出?我迷路了 在JVM的标准输出所在的同一位置。如果您有一个Tomcat服务器,这将是catalina_u2;(date).out文件。线程转储将从执行kill-3的VM写入系统。如果将JVM的控制台输出重定向到一个文件,线程转储将在该文件中。如果JVM在开放控制台中运行,那么线程转储将显示在其控制台中。您也可以使用jstack(包含在JDK中)进行线程转储,并在任何需要的地方写入输出。这在unix环

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

在JVM的标准输出所在的同一位置。如果您有一个Tomcat服务器,这将是
catalina_u2;(date).out
文件。

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

您也可以使用jstack(包含在JDK中)进行线程转储,并在任何需要的地方写入输出。这在unix环境中不可用吗

jstack PID > outfile

有一种方法可以将JVM线程转储输出的中断信号重定向到单独的文件:


在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>
nohup$JBOSS\u HOME/bin/run.sh-c yourinstancename$JBOSS\u OPTS>>控制台-$(日期+%Y%m%d)。输出2>&1

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

使用kill-3时,应该可以在标准输出中看到线程转储。大多数应用服务器将标准输出写入一个单独的文件。你应该在使用kill-3时找到它。有多种获取线程转储的方法:

  • kill-3
    :将输出提供给标准输出
  • 如果可以访问服务器运行的控制台窗口,可以使用Ctrl+Break组合键在STDOUT上生成堆栈跟踪
  • 对于hotspot 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]
    
    用法:
    jstack[-l](连接到正在运行的进程)
    jstack-F[-m][-l](连接到挂起的进程)
    -对于JRockit JVM,我们可以使用JDK语法附带的JRCMD命令:
    jrcmd[[]][-l][-f文件][-p]-h]
    
  • 查找进程id[PS id]
  • 执行jcmd[PS ID]Thread.print

  • 有了Java8,首选的方法是
    jcmd

    jcmd <PID> Thread.print
    
    jcmd Thread.print
    
    以下是中的代码段:

    JDK 8的发布引入了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获取child

    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进程的进程id。i、 e.8536

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

    你在扼杀哪个过程?它是J2EE应用程序服务器吗?如果是这样的话,您应该在标准输出中找到堆栈跟踪。我正在杀死一个运行java类的进程,该进程在控制台上写入线程转储。由于java类在运行时将控制台设置为std outYes。您还可以为一个长列表指定-l(小写l),该列表打印额外的锁信息,直到jstack命令由于“无法从地址推断线程类型”而一致失败-(如果您看到这个错误,我建议您与供应商联系。例如,快速搜索显示,RHEL中有一个关于这个错误和openjdk的开放bug……值得注意的是,jstack需要JDK。如果您在只安装了JRE的服务器上运行应用程序,您需要找到另一种线程转储方法。下面是h如何使用jstack获取在不同用户下运行的进程的线程转储,如windows服务:有一种方法可以将JVM线程转储输出重定向到单独的文件。请参见我的回答。从技术上讲,这不会“重定向”线程转储输出。它会将JVM日志记录到JVM.log(包括线程转储输出)但是kill-QUIT仍然会转储到进程的stdout中不幸的是,
    jcmd
    无法使用
    com.sun.tools.attach.AttachNotSupportedException连接到windows服务进程:内存不足或权限不足,无法连接
    ,而
    jstack-F
    成功:您需要在与java进程相同的用户下运行jcmd Thread.dump,否则,您的连接将断开。看,我在使用Kill-3时遇到了麻烦。它工作正常,但在将线程转储写入控制台后也会终止进程。它应该这样做吗?@Ashley-no
    kill-3
    不应该杀死JVM。你在看什么类型的Java应用程序?
    linux$ jstack **8536** > threadDump.log