
我必須創建堆轉儲,這與 jmap 配合得很好。我的問題是,jmap 需要很長時間才能建立堆轉儲檔案。特別是當堆變得越來越大(> 1GB)時,它花費的時間太長。
例如一種情況:
當伺服器遇到堆空間問題時,我想自動重新啟動它並在重新啟動之前建立一個堆轉儲。這可行,但寫入堆轉儲需要很長時間。這樣伺服器就宕機太久了。堆轉儲創建需要超過一小時。
我知道-XX:+HeapDumpOnOutOfMemoryError
,但是大多數時候我可以在jvm拋出異常之前找到內存問題。
jmap 是否有替代方案可以更快地寫入堆轉儲?
對於上述範例的特殊解決方案也將受到讚賞。
這個問題是程式設計和系統管理之間的混合,但我認為我處於正確的位置。
答案1
我找到了我的問題的答案。 這關於伺服器故障的另一個問題的回答給了我這個想法。
- 使用 gdb 連接到您的 java 進程
gdb --pid=<your java pid>
- 從 gdb 建立核心轉儲
gcore <file name>
detach
quit - 重新啟動java進程或做你喜歡做的事
- 透過將 jmap 連接到核心轉儲,從核心轉儲建立堆轉儲
jmap -heap:format=b <path to java binary> <core dump file>
在步驟 4 中,指定正確的 java 二進位檔案至關重要,否則 jmap 無法附加到核心轉儲。如果您不確定 java 進程使用了哪個二進位文件,請使用 gdb 開啟核心轉儲:
gdb --core=<core dump file>
將會有這樣一行,告訴您完整路徑:
Core was generated by '/opt/tomcat/bin/jsvc'.
建立核心轉儲比直接透過 jmap 建立堆轉儲要快得多。透過這種方式,您可以建立 java 進程的堆轉儲,而無需太長時間的停機時間。
編輯:
當您收到以下錯誤訊息時,可能是您指定了錯誤的 java 二進位檔案:
Error attaching to core file: Can't attach to the core file
若要取得 jmap 呼叫的正確 java 二進位文件,請使用 gdb 開啟核心轉儲:
gdb --core=[path tp core file]
將會有這樣一行,告訴你正確的二進位檔案:
Core was generated by `/opt/tomcat/bin/jsvc'.