如何在Linux / Unix上生成Java线程转储?

环境

  • 爪哇
  • Linux和大多数类似Unix的环境

问题

  • 在Linux上运行时,如何在JBoss中生成线程转储?
  • 如何在Linux上生成JBoss堆栈跟踪?
  • 如何将kill -3的输出重定向到文件?
  • JBoss的cpu使用率很高,冻结,挂起或不释放空闲线程,如何获取线程转储进行故障排除?
  • JMS消息丢失了,如何生成线程转储以进行调查?
  • 无法在server.log或console.log中使用Kill -3进行线程转储

解析度


免责声明:此处包含的指向外部网站的链接仅出于方便目的而提供。红帽尚未审查这些链接,并且对其内容或其可用性不承担任何责任。包含任何指向外部网站的链接并不意味着Red Hat认可该网站或其实体,产品或服务。您同意Red Hat对因您使用(或依赖)外部站点或内容而导致的任何损失或费用不承担任何责任。


选择以下方法之一在Unix上生成Java线程转储:

注意:通常,只要捕获线程转储,就会提供gc日志记录。过多的gc可能会导致线程问题,因此gc和线程转储分析是并驾齐驱的。

选项1:OpenJDK / Sun JDK

使用jps -lv可以找到Java进程ID发放kill -QUITkill -3
确保-Xrs未使用JVM选项,因为它会导致忽略SIGQUITSIGWAITING信号。正在运行会kill -3SIGQUITJVM发送信号,因此使用此选项将导致kill -3被忽略。请参阅Java应用程序启动器

如果使用OpenJDK或Sun JDK 1.6或更高版本,则使用jstack选项。当出于某种原因将标准重定向到文件有问题时,这很有用(例如,不希望仅出于将标准重定向到JVM而重新启动JVM)。输入Java进程ID,执行以下操作:

jstack -l JAVA_PID > jstack.out

注意Java进程的进程ID号码(例如,使用top中,grepps -axw,等)并发送一个QUIT信号给过程中与kill -QUITkill -3命令1。例如:

kill -3 JAVA_PID

选项2:kill -3Linux脚本(非连续)

下载threaddump_linux.sh.tar.gzthreaddump_solaris.sh.tar.gz,然后解压缩脚本。使脚本可执行chmod 755

该脚本将捕获一系列6个线程转储,它们间隔20秒(可以根据需要进行修改),并传入Java进程ID作为参数。例如:

Linux: sh ./threaddump_linux.sh JAVA_PID
Solaris: bash ./threaddump_solaris.sh JAVA_PID

确保在问题发生之前测试脚本,以确保脚本在您的环境中正常运行。

选项3:kill -3Linux脚本(连续)

下载threaddump_linux-continuous.sh.tar.gzthreaddump_solaris-continuous.sh.tar.gz,然后解压缩脚本。使脚本可执行chmod 755

它将捕获相距20秒(根据需要进行修改)的线程转储,并将Java进程ID作为参数传入。例如:

扫描二维码关注公众号,回复: 13125774 查看本文章
Linux: sh ./threaddump_linux-continuous.sh JAVA_PID
Solaris: bash ./threaddump_solaris-continuous.sh JAVA_PID

确保在问题发生之前测试脚本,以确保脚本在您的环境中正常运行。

选项4:JBoss EAP参数

使用以下命令启动JBoss实例,然后用于kill -3生成线程转储。

如果Java应用程序使用记录控制台输出的服务脚本启动,则线程转储将在控制台日志中。否则,stdout在启动时重定向到文件。

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

这会将您的输出/转储重定向到上述命令中指定的文件控制台。

选项5:jstack linux脚本(连续)

下载linux_jstack-continuous.tar.gz并解压缩脚本。chmod 755
使用Jstack使其可执行脚本。它将使用jstack捕获一系列6个线程转储,它们间隔20秒(根据需要进行修改),并传入Java进程ID作为参数。确保JAVA_HOME在此脚本中进行设置。它会jstack_threaddump.out在执行该脚本的目录中生成一个名为的文件。例如:

./threaddump_linux_jstack-continuous.sh JAVA_PID

选项6:IBM J9

IBM J9拥有自己的监视工具,即Java-TMDA的IBM线程和监视器转储分析器。但是,kill -3 PID仍然可以用来生成线程转储,如请参阅选项1:OpenJDK / Sun JDK kill -3部分中所述。

可以在OpenJ9 Docs-Java Dumps中找到更多信息。

笔记

  • 使用ps aux命令(R或列中的S状态STAT)验证Java进程是否仍在运行。例如,jstack -F <pid>将目标Java进程置于“跟踪停止”(T)状态。处于(T)状态的线程将接收线程转储的信号;但是,输出将延迟到该过程继续进行。
  • 您需要确保jstack从与Java进程相同的用户处执行命令。请参阅在执行jstack / jmap / jcmd且无法生成线程转储/堆转储时获取“无法打开套接字文件”消息,以获取更多详细信息。
  • 存在与使用其他jstack选项(例如-F-m等)有关的已知错误和/或线程转储工具无法解析输出,因此,如果-l建议使用除其他选项之外的其他选项,请确保测试捕获和解析输出。
  • 在某些情况下,运行jstack可能会影响性能。据报道,在某些情况下运行jstack时,可以观察到响应时间变慢。
  • 如果要进行线程转储以标识哪些Java线程消耗了较高的cpu,请参见如何在Linux / Solaris上确定Java线程的CPU使用率,并在本文中使用随附的示例脚本。

JBoss EAP 5.x

stdout在启动时重定向到文件:

sh run.sh > console.log 2>&1

如果重定向时遇到问题stdout,请修改$JBOSS_HOME/bin/run.sh并更改该行:

org.jboss.Main "$@"

阅读:

org.jboss.Main "$@" > console.log

正常保存并重新启动JBoss。现在kill -3还是kill -QUIT应该在文件中创建一个线程转储console.log

JBoss EAP 7.x / 6.x

建议使用jstack。请参阅选项5:jstackLinux脚本(连续)

JBoss保险丝6

如果要从子容器捕获线程转储,请注意该过程与根容器不同。选择用于运行脚本的PID之前,请确保使用“ ps”或类似的命令检查进程ID(PID)。例如:

ps -ef | grep child1

testusr 27803     1  0 09:41 pts/1    00:00:12 /usr/java/jdk1.7.0_21/jre/bin/java -server ... -Dkaraf.home=/home/testusr/apps/product-distributions -Dkaraf.base=/home/testusr/apps/product-distributions/instances/child1  org.apache.karaf.main.Main

有关的

如何确定Linux / Solaris上Java线程的CPU使用率高


  1. 注意: kill -3命令不会直接从命令行产生输出到文件。相反,它将产生console output对其调用的过程的输出。对于JBoss EAP域模式服务器,默认情况下应在主机控制器日志中捕获其控制台输出。 

附件

猜你喜欢

转载自blog.csdn.net/allway2/article/details/115349593
今日推荐