[轉帖]獲取一直FullGC下的java進程HeapDump的小技巧

https://plantegg.github.io/2020/01/04/%E8%8E%B7%E5%8F%96%E4%B8%80%E7%9B%B4FullGC%E4%B8%8B%E7%9A%84java%E8%BF%9B%E7%A8%8BHeapDump%E7%9A%84%E5%B0%8F%E6%8A%80%E5%B7%A7/

 

就是小技巧,操作步驟需要查詢,隨手記錄

  • 找到java進程,gdb attach上去, 例如 gdb -p 12345
  • 找到這個HeapDumpBeforeFullGC的地址(這個flag如果爲true,會在FullGC之前做HeapDump,默認是false)
1
2
(gdb) p &HeapDumpBeforeFullGC
$2 = (<data variable, no debug info> *) 0x7f7d50fc660f <HeapDumpBeforeFullGC>
  • Copy 地址:0x7f7d50fc660f
  • 然後把他設置爲true,這樣下次FGC之前就會生成一份dump文件
1
2
(gdb) set *0x7f7d50fc660f = 1
(gdb) quit
  • 最後,等一會,等下次FullGC觸發,你就有HeapDump了!
    (如果沒有指定heapdump的名字,默認是 java_pidxxx.hprof)

(PS. jstat -gcutil pid 可以查看gc的概況)

(操作完成後記得gdb上去再設置回去,不然可能一直fullgc,導致把磁盤打滿).

其它

在jvm還有響應的時候可以: jinfo -flag +HeapDumpBeforeFullGC pid 設置HeapDumpBeforeFullGC 爲true(- 爲false,+-都不要爲只打印值)

kill -3 產生coredump 存放在 kernel.core_pattern=/root/core (/etc/sysctl.conf)

得到core文件後,採用 gdb -c 執行文件 core文件 進入調試模式,對於java,有以下2個技巧:

進入gdb調試模式後,輸入如下命令: info threads,觀察異常的線程,定位到異常的線程後,則可以輸入如下命令:thread 線程編號,則會打印出當前java代碼的工作流程。

而對於這個core,亦可以用jstack jmap打印出堆信息,線程信息,具體命令:

jmap -heap 執行文件 core文件 jstack -F -l 執行文件 core文件

容器中的進程的話需要到宿主機操作,並且將容器中的 jdk文件夾複製到宿主機對應的位置。

ps auxff |grep 容器id -A10 找到JVM在宿主機上的進程id

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章