paulwong

          各種獲取JVM DUMP的方法

          JVM 的線程堆棧 dump 也稱 core dump,內(nèi)容為文本,主要包含當(dāng)時(shí) JVM 的線程堆棧,堆 dump 也稱 heap dump,內(nèi)容為二進(jìn)制格式,主要包含當(dāng)時(shí) JVM 堆內(nèi)存中的內(nèi)容。由于各個(gè)操作系統(tǒng)、各個(gè) JVM 實(shí)現(xiàn)不同,即使同一 JVM 實(shí)現(xiàn),各個(gè)版本也有差異,本文描述的方法都基于 64 位 Linux 操作系統(tǒng)環(huán)境,Java 8 Oracle HotSpot JVM 實(shí)現(xiàn)。

          堆棧和堆的內(nèi)容在定位問(wèn)題的時(shí)候,都是非常重要的信息。線程堆棧 dump 可以了解當(dāng)時(shí) JVM 中所有線程的運(yùn)行情況,比如線程的狀態(tài)和當(dāng)前正在運(yùn)行的代碼行。堆 dump 可以了解當(dāng)時(shí)堆的使用情況,各個(gè)類實(shí)例的數(shù)量及各個(gè)實(shí)例所占用的空間大小。

          線程堆棧

          使用 jstack

          jstack 是 JDK 自帶的工具,用于 dump 指定進(jìn)程 ID(PID)的 JVM 的線程堆棧信息。

          # 打印堆棧信息到標(biāo)準(zhǔn)輸出 jstack PID  
          # 打印堆棧信息到標(biāo)準(zhǔn)輸出,會(huì)打印關(guān)于鎖的信息 jstack -l PID  
          強(qiáng)制打印堆棧信息到標(biāo)準(zhǔn)輸出,如果使用 jstack PID 沒(méi)有響應(yīng)的情況下(此時(shí) JVM 進(jìn)程可能掛起),
          加 -F 參數(shù) jstack -F PID 

          使用 jcmd

          jcmd 是 JDK 自帶的工具,用于向 JVM 進(jìn)程發(fā)送命令,根據(jù)命令的不同,可以代替或部分代替 jstack、jmap 等。可以發(fā)送命令 Thread.print 來(lái)打印出 JVM 的線程堆棧信息。

          # 下面的命令同等于 jstack PID 
          jcmd PID Thread.print  

          # 同等于 jstack -l PID 
          jcmd PID Thread.print -l 

          使用 kill -3

          kill 可以向特定的進(jìn)程發(fā)送信號(hào)(SIGNAL),缺省情況是發(fā)送終止(TERM) 的信號(hào) ,即 kill PID 與 kill -15 PID 或 kill -TERM PID 是等價(jià)的。JVM 進(jìn)程會(huì)監(jiān)聽(tīng) QUIT 信號(hào)(其值為 3),當(dāng)收到這個(gè)信號(hào)時(shí),會(huì)打印出當(dāng)時(shí)的線程堆棧和堆內(nèi)存使用概要,相比 jstack,此時(shí)多了堆內(nèi)存的使用概要情況。但 jstack 可以指定 -l 參數(shù),打印鎖的信息。

          kill -3 PID 
          # 或 kill -QUIT PID 

          -XX:+HeapDumpOnOutOfMemoryError

          添加 JVM 參數(shù) -XX:+HeapDumpOnOutOfMemoryError 后,當(dāng)發(fā)生 OOM(OutOfMemory)時(shí),自動(dòng)堆 dump。缺省情況下,JVM 會(huì)創(chuàng)建一個(gè)名稱為 java_pidPID.hprof 的堆 dump 文件在 JVM 的工作目錄下。但可以使用參數(shù) -XX:HeapDumpPath=PATH 來(lái)指定 dump 文件的保存位置。

          # JVM 發(fā)生 OOM 時(shí),會(huì)自動(dòng)在 /var/log/abc 目錄下產(chǎn)生堆 dump 文件 java_pidPID.hprof 
          java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/abc/ 

          jmap

          jmap 也是 JDK 自帶的工具,主要用于獲取堆相關(guān)的信息。

          堆 dump

          # 將 JVM 的堆 dump 到指定文件,如果堆中對(duì)象較多,需要的時(shí)間會(huì)較長(zhǎng),子參數(shù) format 只支持 b,
          即二進(jìn)制格式
          jmap -dump:format=b,file=FILE_WITH_PATH

          # 如果 JVM 進(jìn)程未響應(yīng)命令,可以加上參數(shù) -F 嘗試
          jmap -F -dump:format=b,file=FILE_WITH_PATH

          # 可以只 dump 堆中的存活對(duì)象,加上 live 子參數(shù),但使用 -F 時(shí)不支持 live
          jmap -dump:live,format=b,file=FILE_WITH_PATH

          獲取堆概要信息

          # -heap 參數(shù)用于查看指定 JVM 進(jìn)程的堆的信息,包括堆的各個(gè)參數(shù)的值,堆中新生代、年老代的內(nèi)存大小、使用率等 
          jmap -heap PID  

          # 同樣,如果 JVM 進(jìn)程未響應(yīng)命令,可以加上參數(shù) -F 嘗試 
          jmap -F -heap PID 

          一個(gè)實(shí)例輸出如下:

          Attaching to process ID 68322, please wait
          Debugger attached successfully.
          Server compiler detected.
          JVM version is 25.112-b16

          using thread-local object allocation.
          Parallel GC with 4 thread(s)

          Heap Configuration:
             MinHeapFreeRatio         = 0
             MaxHeapFreeRatio         = 100
             MaxHeapSize              = 268435456 (256.0MB)
             NewSize                  = 8388608 (8.0MB)
             MaxNewSize               = 89128960 (85.0MB)
             OldSize                  = 16777216 (16.0MB)
             NewRatio                 = 2
             SurvivorRatio            = 8
             MetaspaceSize            = 21807104 (20.796875MB)
             CompressedClassSpaceSize = 1073741824 (1024.0MB)
             MaxMetaspaceSize         = 17592186044415 MB
             G1HeapRegionSize         = 0 (0.0MB)

          Heap Usage:
          PS Young Generation
          Eden Space:
             capacity = 41943040 (40.0MB)
             used     = 1701504 (1.6226806640625MB)
             free     = 40241536 (38.3773193359375MB)
             4.05670166015625% used
          From Space:
             capacity = 4194304 (4.0MB)
             used     = 0 (0.0MB)
             free     = 4194304 (4.0MB)
             0.0% used
          To Space:
             capacity = 5242880 (5.0MB)
             used     = 0 (0.0MB)
             free     = 5242880 (5.0MB)
             0.0% used
          PS Old Generation
             capacity = 30408704 (29.0MB)
             used     = 12129856 (11.56793212890625MB)
             free     = 18278848 (17.43206787109375MB)
             39.889421134159484% used

          16658 interned Strings occupying 1428472 bytes.

          獲取堆中的類實(shí)例統(tǒng)計(jì)
          # 打印 JVM 堆中的類實(shí)例統(tǒng)計(jì)信息,以占用內(nèi)存的大小排序,同樣,如果 JVM 未響應(yīng)命令,也可以使用 -F 參數(shù) 
          jmap -histo PID  

          # 也可以只統(tǒng)計(jì)堆中的存活對(duì)象,加上 live 子參數(shù),但使用 -F 時(shí)不支持 live 
          jmap -histo:live PID 

          使用 jcmd

          # 等同 jmap -dump:live,format=b,file=FILE_WITH_PATH
          jcmd PID GC.heap_dump FILE_WITH_PATH

          # 等同 jmap -dump:format=b,file=FILE_WITH_PATH
          jcmd PID GC.heap_dump -all FILE_WITH_PATH

          # 等同 jmap -histo:live PID
          jcmd PID GC.class_histogram

          # 等同 jmap -histo PID
          jcmd PID GC.class_histogram -all

          posted on 2020-02-24 22:03 paulwong 閱讀(1252) 評(píng)論(0)  編輯  收藏 所屬分類: J2SE性能優(yōu)化 、JVM

          主站蜘蛛池模板: 武安市| 正安县| 天台县| 金门县| 德令哈市| 华安县| 晋江市| 永宁县| 靖宇县| 襄汾县| 深圳市| 汾西县| 富阳市| 清镇市| 弥勒县| 宜兰县| 南宫市| 桦甸市| 铅山县| 佳木斯市| 泌阳县| 株洲市| 天全县| 封开县| 顺昌县| 云林县| 弥勒县| 井冈山市| 苏尼特右旗| 庆安县| 腾冲县| 铜山县| 平凉市| 民权县| 丹凤县| 高淳县| 汤阴县| 贵南县| 琼中| 滦南县| 阳东县|