jmap、jstack、jps無法連接jvm解決辦法


轉載 http://blog.51cto.com/zhangshaoxiong/1310166

一、背景

在對線上服務器的java應用dump操作時發現,以下報錯,不能dump。jps也獲取不到java進程的pid。

# jmap -dump:file=/data/dump/jvm_en.hprof 20176

20176: 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

重啟后,jps可以獲得該java進程的pid,jstack也可以dump線程。

而tomcat:

jdk1.6.24版本下的,jps、jstack都無法操作

jdk1.6.18版本可以執行jps、jstack。

二、原因分析

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信息,所以才報錯。

三、解決辦法
3.1 修改tmpwatch設置

排查對應的/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
3.2 修改tomcat配置或者升級jdk

1)修改tomcat的Djava.io.tmpdir參數,統一使用/tmp目錄。

修改catalina.sh添加

CATALINA_TMPDIR=/tmp

重啟tomcat

2)升級jdk到Java 6 update 25.

3.3 其他java程序重啟

重啟java進程,重新生成pid文件。

參考URl:

1. http://pt.alibaba-inc.com/wp/experience_382/java-long-running-jps-tools-such-as-a-solution-can-not-connect-jvm-2.html

2. http://underlap.blogspot.com/2011/03/java-update-breaks-jps-jconsole-etc.html

另外說明:

1、在JDK 64bit 1.7.0_01版本也出現了這個問題。
2、在CentOS6以后,/etc/cron.daily/tmpwatch有所改變
#! /bin/sh
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 \
-X '/tmp/hsperfdata_*' 10d /tmp
/usr/sbin/tmpwatch "$flags" 30d /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do
if [ -d "$d" ]; then
/usr/sbin/tmpwatch "$flags" -f 30d "$d"
fi
done
上面紅色字體就是新加入的。
目錄/etc/cron.daily/,這個目錄是每天執行一次計划任務的目錄,所以說,如果設置了比一天更短的清理時間,它是不起作用的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM