我的 java 进程停止响应。我尝试 jstack 但失败并出现以下错误。
21039: 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
然后我使用了 -F 选项,但是“没有发现死锁。”
其他信息:
java版本:java version
jmap:jmap
jstat:jstat
金信息:jinfo
任何人都可以帮忙看看并分享一些有关解决此类 java“无响应”问题的链接吗?
最佳答案
无法打开套接字文件
问题的可能原因:
- 目标 PID 不是 HotSpot JVM 进程。
这显然不是你的情况,因为jinfo PID
工作正常。 - JVM 使用
-XX:+DisableAttachMechanism
选项启动。
这也可以通过jinfo PID
来验证。 附加套接字
/tmp/.java_pidNNN
已被删除。
有一种常见的做法是使用一些计划脚本自动清理/tmp
。在这种情况下,您应该将清理软件配置为不删除.java_pid*
文件。如何检查:运行
lsof -p PID | grep java_pid
如果它列出了一个套接字文件,但该文件不存在,那么这正是所描述的问题。当前用户的凭据 (
euid
/egid
) 与附加套接字的所有者不匹配。确保由与 JVM 相同的用户运行jstack
。如果您由其他用户运行jstack
,即使该用户是root
,附加也不起作用。
目标进程的 /tmp
目录与 shell 的/tmp
目录不同。在以下情况下可能会发生这种情况:- JVM 在不同的 mount namespace 中启动。通常,当 JVM 在 Docker 容器中运行时会发生这种情况。从同一个容器中运行
jstack
会有所帮助。 - JVM 启动于
chroot
环境。例如,LXC 容器可以使用chroot
。
如何检查:运行readlink -f/proc/PID/root/tmp
看看它是否指向/tmp
或其他目录。
- JVM 在不同的 mount namespace 中启动。通常,当 JVM 在 Docker 容器中运行时会发生这种情况。从同一个容器中运行
目标 JVM 的当前工作目录属于不允许更改权限的文件系统。 CIFS和 DrvFs (WSL) 是此类文件系统的示例。
如何检查:运行
umask 077;触摸/proc/PID/cwd/somefile.tmp
,然后验证文件所有者是您自己,并且文件权限为600
。JVM 正忙,无法到达安全点。例如,JVM 正处于长时间运行的垃圾收集过程中。
如何检查:运行
kill -3 PID
。 JVM 应在其控制台中打印线程转储和堆信息。如果 JVM 没有转储任何内容,但该进程消耗了几乎 100% 的 CPU 或显示出较高的 I/O 利用率,那么这看起来就像所描述的问题。JVM 进程已挂起。
如何检查:运行
ps PID
。 Activity JVM 进程的STAT
列应为Sl
。
More about the internals of jstack.
还有jattach
项目是 jstack
/jmap
更好的替代品。它可以自动处理凭据问题,可以与 Docker 容器配合使用,支持 chroot 的 JVM 并处理不常见的文件系统。
关于java - 分析java进程 "not responding"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53879015/