JDK14性能管理工具:jmap和jhat使用介紹


簡介

我們在寫代碼的過程中,經常會遇到內存泄露的問題,比如某個集合中的對象沒有被回收,或者內存出現不明原因的增長。這些都是需要我們來定位的問題,我們可以使用jmap和jhat來對java程序中的內存對象進行分析。

jmap(Java Memory Map)是JDK自帶的工具,用來將某個java程序的內存中的信息打印或者輸出到文件中,然后通過jhat(Java Heap Analysis Tool)工具對輸出的文件進行分析,從而找到可能出現的問題。

更多精彩內容且看:

更多內容請訪問www.flydean.com

接下來進入我們的jmap和jhat之旅吧。

jmap

    jmap -clstats <pid>
        to connect to running process and print class loader statistics
    jmap -finalizerinfo <pid>
        to connect to running process and print information on objects awaiting finalization
    jmap -histo[:[<histo-options>]] <pid>
        to connect to running process and print histogram of java object heap
    jmap -dump:<dump-options> <pid>
        to connect to running process and dump java heap

jmap有下面四個可用選項:

clstats

clstats的全稱叫做class loader statistics,用輸出類加載有關的統計信息。

舉一個例子:

jmap -clstats 8820

輸出結果如下:

  • Index - class的編號
  • Super - 父類的編號
  • InstBytes - 每個instance的bytes大小
  • KlassBytes - 該class的bytes大小
  • annotations - 注解大小
  • CpAll - 每個class中constants, tags, cache, 和 operands的大小
  • MethodCount - class中方法的個數
  • Bytecodes - byte codes的大小
  • MethodAll - method, CONSTMETHOD, stack map, 和 method data的大小
  • ROAll - 可以放到read-only memory中的class元數據的大小
  • RWAll - 可以放到read/write memory中的class元數據大小
  • Total - ROAll + RWAll
  • ClassName - class name

finalizerinfo

finalizerinfo列出准備finalization的對象。

jmap -finalizerinfo 8820

如果沒有對象等待被finalization,則會輸出:

No instances waiting for finalization found

histo

histo用來輸出java heap對象的直方圖。可以加一個live選項,用來輸出live的對象。

jmap -histo:live 8820

輸出結果:

num是對象的編號,instances是對象的個數,bytes是對象的大小,class name是對象的class名字。

dump

最后要講一下dump,dump用於dump整個java heap,dump可以接三個參數:

  • live - dump live對象
  • format=b - 以hprof的二進制模式dump
  • file=filename - dump對象到文件中
jmap -dump:live,file=dump.log 8820

這里dump.log文件是非常大的,用肉眼也很難分析,下面我們介紹一下jhat(Java Heap Analysis Tool)命令來對dump出來的對象進行分析。

jhat

注意,jhat從JDK9的時候已經刪除了(JEP 241: Remove the jhat Tool)。現在Oracle官方推薦的分析工具是Eclipse Memory Analyzer Tool (MAT) 和 VisualVM。 這兩款工具后面有時間再詳細講解。

今天先使用JDK8中的jhat來分析一下上面dump出來的文件。

先看下jhat的命令格式:

Usage:  jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>

	-J<flag>          Pass <flag> directly to the runtime system. For
			  example, -J-mx512m to use a maximum heap size of 512MB
	-stack false:     Turn off tracking object allocation call stack.
	-refs false:      Turn off tracking of references to objects
	-port <port>:     Set the port for the HTTP server.  Defaults to 7000
	-exclude <file>:  Specify a file that lists data members that should
			  be excluded from the reachableFrom query.
	-baseline <file>: Specify a baseline object dump.  Objects in
			  both heap dumps with the same ID and same class will
			  be marked as not being "new".
	-debug <int>:     Set debug level.
			    0:  No debug output
			    1:  Debug hprof file parsing
			    2:  Debug hprof file parsing, no server

因為這個命令已經被廢棄了,這里就不過多講解它的參數,總體來說jhap會解析dump出來的文件,並在本地啟動一個web服務器,我們可以通過web頁面來查看dump出來的數據。默認情況下web服務器的端口是7000。

jhat dump.log
Reading from dump.log...
Dump file created Mon May 11 21:13:43 CST 2020
Snapshot read, resolving...
Resolving 197989 objects...
Chasing references, expect 39 dots.......................................
Eliminating duplicate references.......................................
Snapshot resolved.

打開localhost:7000,我們可以看到首頁展示的是各個包中的類的實例和地址信息:

點擊首頁的類的鏈接,可以跳轉到類的具體信息頁面:

類的信息頁面包含很多信息,包括父類,類加載器,簽名,安全域,子類,實例,引用等詳細信息。

對我們分析內存泄露和內存異常等情況非常有用。

總結

本文介紹了jmap和jhat的使用。

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/jdk14-jmap-jhat/

本文來源:flydean的博客

歡迎關注我的公眾號:程序那些事,更多精彩等着您!


免責聲明!

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



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