48

我正在运行 Ubuntu 服务器版,我想进行 Tomcat 的线程转储。

所以,我首先尝试找出tomcat使用的是哪个PID:

$ jps -l
5809 sun.tools.jps.Jps

但它不在那里?

所以,我top改用并找到了 PID 5730。

然后我调用 jstack 来获取线程转储:

$ sudo jstack -l 5730
5730: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

这是怎么回事?:-(

我已经尝试按照Jstack 中的描述导出 CATALINA_TMPDIR 并且 Jstat 停止升级到 JDK6u23但这并没有改变任何东西:

$ export CATALINA_TMPDIR=/tmp
$ sudo /etc/init.d/tomcat6 restart
 * Stopping Tomcat servlet engine tomcat6
   ...done.
 * Starting Tomcat servlet engine tomcat6
   ...done.
$ sudo jstack -l 5934 // new PID after restart
5934: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

更新:

我也尝试过sudo -u tomcat6 jstack -l -F 5730 > threaddumpexceptions2.txt,但它只会给我控制台上的大量异常。

4

10 回答 10

75

我通过做两件事让它工作:

  1. 将调用更改为:sudo -u tomcat6 jstack -J-d64 -m pid
  2. 用 Sun 的原始 sun-6-jdk 和 sun-6-jre 包替换 OpenJDK

第 1 部分说明:我切换到 64 位模式,sudo以 Tomcat 用户身份使用并运行命令。

注意:第 2 部分可能不是必需的。对于某些用户来说,第 1 部分似乎就足够了。实际上,请先尝试仅添加sudo命令。它可能已经成功了。

于 2011-09-28T15:16:03.707 回答
33

我认为您需要以运行 Tomcat 进程的同一用户身份运行 jstack。另请注意, jps 仅返回当前用户的进程。您可以通过使用 sudo 或作为 Tomcat 进程用户运行 jps 来获取 Tomcat 进程的 pid。

此错误报告也可能有用:https ://bugs.launchpad.net/ubuntu/+source/sun-java6/+bug/597098

于 2011-09-14T18:10:07.660 回答
4

@Valmar,我在这里找到了相同的主题帖子。 无法获取线程转储?任何想法为什么我的应用程序阻塞?

似乎解决方法是sudo -u tomcat6 kill -3 <pid>.

于 2011-09-24T12:38:12.167 回答
3

尝试切换到进程用户,然后使用 jstack:

sudo -u {进程用户} jstack > 转储

于 2015-07-21T02:49:29.000 回答
1

这也对我有用:

sudo -u tomcat6 杀死 -3 pid

看起来什么都没有发生,但是当您查看日志时,堆栈就在那里。如果您不期待它们,它们看起来像例外。

于 2012-04-05T01:53:51.320 回答
1

我发现使用类似 'ps -eo pid,user,command | 的东西很有用。grep java' 查找正在使用的实际 java 命令,然后使用该目录查找匹配的 jstack 等。

# ps -eo user,command | grep '[j]ava' | cut -d' ' -f1
someuser /usr/lib/jvm/java/bin/java

# /usr/lib/jvm/java/bin/java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)

所以它是 64 位的,以“someuser”身份运行。su 到该用户并从同一目录运行运行 jstack 等。(即/usr/lib/jvm/java/bin/jstack

当您在具有各种不同 Java 安装/实现的服务器上时很有用。

于 2014-05-01T04:56:06.763 回答
0

我有同样的问题,但以下解决方案都不适合我:

jstack <pid>
jstack -J-d64 -m <pid>
sudo -u <user> jstack ...

我终于将 JDK 从jdk1.6.0_24升级到jdk1.7.0_67并且一切正常。

于 2014-11-08T14:01:21.550 回答
0

对于遇到此问题的 Tomcat 用户,请检查您的 catalina.out 日志文件。

我遇到了同样的问题“22693:无法打开套接字文件:目标进程没有响应或未加载 HotSpot VM”。我放弃了,并试图找到任何关于它锁定之前发生的事情,但是日志文件中有 jstack 输出。

于 2017-04-28T13:35:48.277 回答
0

对于那些在被问到六年后找到这个答案并且他们在CentOS 7上的人,请注意 SELinux 将阻止 jmap 写入堆转储,因为开箱即用,它将拒绝写入套接字,除非目录具有 type tomcat_tmp_t

就我而言,我将堆转储写在/usr/share/tomcat/.jmap. 该目录归我的运行时用户所有。

因此要允许 jmap 写入该目录:

semanage fcontext -a -t tomcat_tmp_t "/usr/share/tomcat/.jmap(/.*)?"
restorecon /usr/share/tomcat -vR

这允许我们作为我们的 tomcat 用户运行:

jmap -dump:format=b,file=/usr/share/tomcat/.jmap/tomcat-`date +%s`.bin <pid>
于 2018-04-11T14:17:43.530 回答
0

我的问题是,我通过终端运行了这个过程。然后为了测试它的 jstack,我暂停了这个过程ctrl+z。进程无法响应。为了解决这个问题,我通过另一个终端恢复了进程fg并检查了它的 jstack。

于 2020-01-28T16:44:48.723 回答