背景
日前伺服器一個應用總是莫名挂掉,通過排查發現是老年代記憶體無法回收引起,那麼要定位到到底是那一部分資料導緻的無法回收,就需要把堆記憶體dump出來,然後用工具分析。但奇怪的是dump的時候一直報錯
Unable to open socket file: target process not responding or HotSpot VM not lo
排查完整過程
解決方案
網上找了很多方案,都沒效果,最終通過一些文章的啟示,自己找到了解決方案。
問題引起的原因
由于Linux一切皆檔案的特性,也就是說一個Java程序實際上會對應到一個PID檔案,dump指令依賴于程序的PID檔案,報錯這個是由于這個PID檔案可能已經被系統給删除了。
linux系統有個删除管理機制:系統每天會用tmpwatch指令檢查并删除 /tmp 下超過240小時未通路過的檔案和目錄。
問題的解決方案
Linux有個檔案(
/usr/lib/tmpfiles.d/tmp.conf
)中記錄着一些目錄,這些目錄中不會被自動删除,我們需要在這個檔案中配置我們的JAVA程序的PID目錄。
第一步:先找到PID所在目錄
先用JPS指令得到程序号
32383為我的JAVA應用的程序号,然後我們去
/tmp
目錄下找這個程序号
很明顯這裡沒有32383,但這裡有個
hsperfdata_root
目錄不知道是什麼東西,進去看看
這裡有31383,那麼也就是說
/tmp/hsperfdata_root
目錄即是要排除在外的目錄。
第二步:把找到的目錄添加到檔案内容中
vi /usr/lib/tmpfiles.d/tmp.conf
添加如下内容
/*
代表目錄下的所有檔案,添加之後應該是立即生效的,無需重新開機。如此,即可避免檔案被系統删掉。
其他事項
以上解決方案是我在我的系統中親測成功的方案,由于系統版本不同,我的解決辦法可能不适用于你,你需要嘗試。
我的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
這個檔案,存在的話可以在這個檔案中添加排除項,添加方式與本文一緻。