在对线上服务器的java应用dump操做时发现,如下报错,不能dump。jps也获取不到java进程的pid。html
# jmap -dump:file=/data/dump/jvm_en.hprof 20176java
20176: Unable to open socket file: target process not responding or HotSpot VM not loadedlinux
The -F option can be used when the target process is not respondingtomcat
重启后,jps能够得到该java进程的pid,jstack也能够dump线程。服务器
而tomcat:jvm
jdk1.6.24版本下的,jps、jstack都没法操做socket
jdk1.6.18版本能够执行jps、jstack。ide
jvm运行时会生成一个目录hsperfdata_$USER($USER是启动java进程的用户),在linux中默认是/tmp。目录下会有些pid文件,存放jvm进程信息。工具
jps、jstack等工具读取/tmp/hsperfdata_$USER下的pid文件获取链接信息。字体
2.1jstack报错缘由
jstack报错:Unable to open socket file。是由于这个java进程的pid文件删除了。
为何会被删除呢?这是由于linux操做系统为了防止/tmp目录文件过多,有个删除管理机制:tmpwatch。
查看关键配置/etc/cron.daily/tmpwatch:
flags=-umc /usr/sbin/tmpwatch "$flags"
-x /tmp/.X11-unix -x /tmp/.XIM-unix \
-x /tmp/.font-unix -x /tmp/.ICE-unix
-x /tmp/.Test-unix 240 /tmp /usr/sbin/tmpwatch "$flags" 720 /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?};
do if [ -d "$d" ]; then /usr/sbin/tmpwatch "$flags" -f 720 "$d" fi done
系统天天会用tmpwatch命令检查并删除 /tmp 下超过240小时未访问过的文件和目录。
2.2高版本jps、jstack不能工做缘由
这是一个从Java 6 update 21 引入的bug sunbug 7009828,在Java 6 update 25修复。具体缘由是:
jdk16_21/24开始,jvm启动时产生进程号的临时文件目录优先使用-Djava.io.tmpdir指定的目录,没有指定-Djava.io.tmpdir参数才使用/tmp/hsperfdata_$USER。
正好tomcat指定了-Djava.io.tmpdir=${tomcat_home}/tmp/。而jps、jstack从/tmp/hsperfdata_$USER目录读取不到pid信息,因此才报错。
排查对应的/tmp/hsperfdata_*的目录,让jvm本身来管理,保证jps,jstat等命令可用。
修改/etc/cron.daily/tmpwatch
/usr/sbin/tmpwatch "$flags" -x /tmp/hsperfdata_* -x /tmp/.X11-unix -x /tmp/.XIM-unix
-x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp
1)修改tomcat的Djava.io.tmpdir参数,统一使用/tmp目录。
修改catalina.sh添加
CATALINA_TMPDIR=/tmp
重启tomcat
2)升级jdk到Java 6 update 25.
重启java进程,从新生成pid文件。
参考URl:
2. http://underlap.blogspot.com/2011/03/java-update-breaks-jps-jconsole-etc.html
另外说明: