監控JVM內存使用情況


1 JDK 工具的使用

JDK自帶的工具位於${JAVA_HOME}/bin/目錄下.

 

JConsole 可以簡單明了地查看到內存的使用情況, 線程的狀態, 當前加載的類的總量等.

JVisualVM 可以下載插件(如GC等), 進而查看更豐富的信息. 如果是分析本地的Tomcat的話, 還可以進行內存抽樣等, 檢查每個類的使用情況.

(1) jps 查看本地運行着的 Java 進程, 及其進程號、進程啟動的路徑等信息;

(2) jmap 查看垃圾收集策略即 JVM 內存占用情況:

jmap -heap pid # 查看垃圾收集策略, 以及堆內存的分配與使用情況.
jmap -clstats pid # 查看類加載器的統計數據 —— 此命令調用了sun.jvm.hotspot.runtime.VM.initialize() 方法, 會導致該 pid 對應的 JVM 進程阻塞.
jmap -histo [pid] # 按照內存使用大小倒序列出內存中的實例類型.

 

 

(3) jstack 查看線程棧:

jstack pid # 列出該 pid 對應 JVM 的所有線程棧描述, 主要包括每個線程的狀態以及堆棧內各棧幀的方法全限定名、代碼位置. 注意: 這些信息的顯示只是為了便於開發人員閱讀, 並不是棧中存的就是這些信息.

(4) jstat 實時查看堆內存的使用情況:

# 使用方法:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

 

# 查看可使用的選項: 
jstat –options 
-class            # 類加載情況的統計
-compiler         # HotSpot中即時編譯器編譯情況的統計
-gc
-gccapacity       # 新生代、老年代以及永久代的存儲容量情況
-gccause
-gcmetacapacity   # 元數據區的容量
-gcnew            # 新生代垃圾回收信息
-gcnewcapacity    # 新生代的存儲容量
-gcold            # 老年代垃圾回收信息
-gcoldcapacity    # 老年代的存儲容量
-gcutil           # 實時查看GC信息
-printcompilation # HotSpot編譯方法的統計

 

  • 使用示例: 間隔5s, 每隔10條輸出一次頭信息, 打印進程號為3308的JVM進程的堆內存使用情況, 以及各代垃圾回收的次數及時間:
    jstat -gcutil -h10 77545 5000

  • 顯示信息如下:

  • 參數說明:

    S0: Heap上的Survivor Space 0區已使用空間的百分比
    S1: Heap上的Survivor Space 1區已使用空間的百分比
    E:  Heap上的Eden Space區已使用空間的百分比
    O:  Heap上的Old Space區已使用空間的百分比
    M:  Meta Space(元數據區)已使用空間的百分比
    YGC: 從應用程序啟動到采樣時發生Young GC的次數
    YGCT: 從應用程序啟動到采樣時Young GC所用的時間(單位: 秒)
    FGC:  從應用程序啟動到采樣時發生Full GC的次數
    FGCT: 從應用程序啟動到采樣時Full GC所用的時間(單位: 秒)
    GCT:  從應用程序啟動到采樣時用於垃圾回收的總時間(單位: 秒)

     

2 查看 GC 日志信息

可以通過配置JVM的啟動參數, 打印類的加載情況及對象的回收信息, 可以打印到屏幕或指定文件中, 默認也會打印到catalina.log中. Tomcat容器的JVM啟動參數配置文件是: ${TOMCAT_HOME}/bin/catalina.sh, 具體參數如下:

-verbose:gc
# 在輸出設備顯示垃圾收集信息(JVM發生內存回收時輸出相關信息)

-XX:+PrintGC
# 輸出GC日志, 形式: Full GC 118250K->113543K(130112K), 0.0094143 secs 

-XX:+PrintGCDetails
# 輸出GC詳細日志, 形式: GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs[Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs] 

-XX:+PrintGCTimeStamps
# 輸出GC的時間戳, 以基准時間的形式輸出: 11.851: [GC 98328K->93620K(130112K), 0.0082960 secs], 11.851是JVM啟動后的秒數.

-XX:+PrintGCDateStamps
# 輸出GC的時間戳, 以日期的形式輸出: 2018-08-28T21:53:59.234+0800

-XX:+PrintGCApplicationStoppedTime
# 打印垃圾回收期間程序暫停的時間, 即GC消耗的時間. 可與上面混合使用. 
# 輸出形式: Total time for which application threads were stopped: 0.0468229 seconds

-XX:+PrintGCApplicationConcurrentTime
# 打印每次垃圾回收前, 程序未中斷的執行時間, 即相鄰2次GC的間隔. 
# 可以和上面的配置混合使用. 輸出形式: Application time: 0.5291524 seconds 

-XX:+PrintTenuringDistribution
# 觀察各個Age的對象總大小

-XX:PrintHeapAtGC
# 打印GC前后的詳細堆棧信息

-XX:+HeapDumpOnOutOfMemoryError
# 發生OOM時自動dump堆棧信息, 以便后續分析

-Xloggc:../logs/gc.log
# 與上面選項配合使用, 將日志信息輸出到指定的文件以便后續分析

 

3 添加 JMS 遠程監控

對部署在局域網內其他服務器上的Tomcat, 可以打開JMX監控端口, 就可以在另外的服務器上通過該端口查看常用的參數(一些比較復雜的功能不支持).

配置方法: 同樣是在JVM啟動參數中配置, 配置如下:

-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=172.16.11.62   # 設置JVM的JMS監聽的IP地址, 防止錯誤監聽為本機127.0.0.1地址
-Dcom.sun.management.jmxremote.port=1090  # 設置JVM的JMS監控的端口
-Dcom.sun.management.jmxremote.ssl=false  # 設置JVM的JMS監控不實用SSL
-Dcom.sun.management.jmxremote.authenticate=false  # 設置JVM的JMS監控不需要認證 

參考資料

JVM 運行時內存使用情況監控

 


免責聲明!

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



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