jstack 解决dump导出JAVA堆内存文件报错
报错信息:
~]$ jstack 283513 > 283513.dump
283513: 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
https://blog.51cto.com/u_15344989/3653973
背景
日前服务器一个应用总是莫名挂掉,通过排查发现是老年代内存无法回收引起,那么要定位到到底是那一部分数据导致的无法回收,就需要把堆内存 dump 出来,然后用工具分析。但奇怪的是 dump 的时候一直报错
Unable to open socket file: target process not responding or HotSpot VM not lo
问题引起的原因
由于 Linux 一切皆文件的特性,也就是说一个 Java 进程实际上会对应到一个 PID 文件,dump 命令依赖于进程的 PID 文件,报错这个是由于这个 PID 文件可能已经被系统给删除了。
问题的解决方案
Linux 有个文件(/usr/lib/tmpfiles.d/tmp.conf)中记录着一些目录,这些目录中不会被自动删除,我们需要在这个文件中配置我们的 JAVA 进程的 PID 目录。
第一步:先找到 PID 所在目录
先用 JPS 命令得到进程号
32383 为我的 JAVA 应用的进程号,然后我们去 /tmp 目录下找这个进程号
很明显这里没有 32383,但这里有个 hsperfdata_root 目录不知道是什么东西,进去看看
这里有 31383,那么也就是说 /tmp/hsperfdata_root 目录即是要排除在外的目录。
/tmp/hsperfdata_appdeploy
第二步:把找到的目录添加到文件内容中
vi /usr/lib/tmpfiles.d/tmp.conf
X /tmp/hsperfdata_appdeploy/*
添加如下内容
/* 代表目录下的所有文件,添加之后应该是立即生效的,无需重启。如此,即可避免文件被系统删掉。
其他事项
以上解决方案是我在我的系统中亲测成功的方案,由于系统版本不同,我的解决办法可能不适用于你,你需要尝试。
我的 Linux 内核版本为 Linux version 3.10.0-1062.1.1.el7.x86_64
系统版本为 CentOS Linux release 7.5.1804
我不确定其他系统版本的设置方式是否一致,有的系统可能没有 /usr/lib/tmpfiles.d/tmp.conf 这个文件,那么可以看看是否存在 /etc/cron.daily/tmpwatch 这个文件,存在的话可以在这个文件中添加排除项,添加方式与本文一致。
如果依然无法解决,可以看看我参考的两篇文章,寻找解决方案。