HPROF: 一個Heap/CPU Profiling工具

無意中看到一篇,寫的非常好。轉載過來。

原文地址:http://www.cnblogs.com/linhaohong/archive/2012/07/12/2588657.html


2SE中提供了一個簡單的命令行工具來對java程序的cpu和heap進行 profiling,叫做HPROF。HPROF實際上是JVM中的一個native的庫,它會在JVM啓動的時候通過命令行參數來動態加載,併成爲 JVM進程的一部分。若要在java進程啓動的時候使用HPROF,用戶可以通過各種命令行參數類型來使用HPROF對java進程的heap或者 (和)cpu進行profiling的功能。HPROF產生的profiling數據可以是二進制的,也可以是文本格式的。這些日誌可以用來跟蹤和分析 java進程的性能問題和瓶頸,解決內存使用上不優的地方或者程序實現上的不優之處。二進制格式的日誌還可以被JVM中的HAT工具來進行瀏覽和分析,用 以觀察java進程的heap中各種類型和數據的情況。

在J2SE 5.0以後的版本中,HPROF已經被併入到一個叫做Java Virtual Machine Tool Interface(JVM TI)中。


HPROF的啓用



HPROF可以用來展示和跟蹤cpu的使用情況,內存分配的統計數據等。不僅如此,它還支持對 java進程完整的內存dump,所有線程的monitor stats數據。HPROF被啓用的方式可以如下: 
java -agentlib:hprof[=options] ToBeProfiledClass 
或者 
java -Xrunhprof[:options] ToBeProfiledClass 
HPROF如何構建java進程,併發送進程的jvm profiling信息,取決於HPROF在JVM啓動時從命令行獲取的參數指令。比如,以下指令將會獲取java進程的heap allocation的profile: 
java -agentlib:hprof=heap=sites ToBeProfiledClass 

HPROF 可以被指定的參數非常的多,以下是完整的列表: 

java -agentlib:hprof=help 


        HPROF: Heap and CPU Profiling Agent (JVM TI Demonstration Code) 

    hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...] 

    Option Name and Value  Description                    Default 
    ---------------------  -----------                    ------- 
    heap=dump|sites|all    heap profiling                 all 
    cpu=samples|times|old  CPU usage                      off 
    monitor=y|n            monitor contention             n 
    format=a|b             text(txt) or binary output     a 
    file=<file>            write data to file             java.hprof[.txt] 
    net=<host>:<port>      send data over a socket        off 
    depth=<size>           stack trace depth              4 
    interval=<ms>          sample interval in ms          10 
    cutoff=<value>         output cutoff point            0.0001 
    lineno=y|n             line number in traces?         y 
    thread=y|n             thread in traces?              n 
    doe=y|n                dump on exit?                  y 
    msa=y|n                Solaris micro state accounting n 
    force=y|n              force output to <file>         y 
    verbose=y|n            print messages about dumps     y 

    Obsolete Options 
    ---------------- 
    gc_okay=y|n 

    Examples 
    -------- 
     - Get sample cpu information every 20 millisec, with a stack depth of 3: 
         java -agentlib:hprof=cpu=samples,interval=20,depth=3 classname 
     - Get heap usage information based on the allocation sites: 
         java -agentlib:hprof=heap=sites classname 

默認情況下,java進程profiling的信息(sites和dump)都會被 寫入到一個叫做java.hprof.txt的文件中。大多數情況下,該文件中都會對每個trace,threads,objects包含一個ID,每一 個ID代表一個不同的觀察對象。通常,traces會從300000開始。 

默認,force=y,會將所有的信息全部輸出到output文件中,所以如果含有 多個JVMs都採用的HRPOF enable的方式運行,最好將force=n,這樣能夠將單獨的JVM的profiling信息輸出到不同的指定文件。 

interval選項只在 cpu=samples的情況下生效,表示每隔多少毫秒對java進程的cpu使用情況進行一次採集。 

msa選項僅僅在Solaris系統下才有效, 表示會使用Solaris下的Micro State Accounting功能 

Examples



我們可以自己寫一個java應用程序,但是例子 裏將使用一個J2SE中已有的java應用程序,javac。 

Heap Allocation Profiles(heap=sites)



以下是對一個java代碼文件運行java編譯 器javac的heap allocation profile日誌的一部分: 
Command used: javac -J-agentlib:hprof=heap=sites Hello.java 


從日誌中可以看到程序在運行的每一個部分都消耗了多少內存的heap profile數據。以上日誌可以看出,整個程序的heap中有44.73%的被分配給了java.util.zip.ZipEntry對象。同時可以觀 察到,live data的數量跟所有allocated的總數是匹配atch的,這就說明GC可能在HPROF遍歷整個heap蒐集信息的很短的時間之前已經做過一次內 存回收了。通常情況下,live data的數量是會稍微少於所有allocated的總數的。 
    
Heap Dump (heap=dump)



該選項用來對java進程的heap進行進行完 全的dump: 
Command used: javac -J-agentlib:hprof=heap=dump Hello.java 
這樣會產生一個非常大的輸出文件,但是可以用任 何編輯器進行打開和搜索。但是,更好的觀察和分析辦法是通過HAT來進行分析和觀察。所有用heap=sites選項中獲取的信息這裏也都可以獲取到。另 外還加上一些特別的細節數據。如對每個對象的內存分配以及其引用的其他所有的對象。 
該選項會使用很多的內存,因爲它會將所有對象的 內存分配情況全部記錄下來,同時也可能會影響到應用程序本身的性能,因爲數據的產生會影響對象分配和資源回收。 

CPU Usage Sampling Profiles (cpu=samples)



HPROF可以用來蒐集java進程中各個threads的cpu使用情況: 


HPROF會對java進程中所有的threads進行週期性的stack traces採集。以上count一列就表示在採集中有多少次的stack trace被HPROF發現,並且是active的(而不是指一個method被執行了多少次)。這些stack traces包括cpu的使用,哪些是cpu消耗熱點。 
那麼以上日誌中可以看出什麼信息呢?第一,統計數據的樣本數據是很少的,只有126次的採樣,如 果是比較大的程序編譯,那麼應該能夠產生更有代表性的數據。第二,該數據跟以上對heap=sites的採集數據比較匹配,ZipFile耗費了比較多的 cpu時間和調用次數。在以上採集中,可以發現,跟ZipFile相關的的性能在javac中都會消耗的比較高,該ZipFile的stack trace如下:


CPU Usage Times Profile (cpu=times)



HPROF可以通過對java應用程序的各個方 法中注入code的方式來蒐集各個method的執行情況。對每個methods的執行情況進行跟蹤,count以及時間消耗的蒐集。這種技術叫做 Byte Code Injection。所以這種採集方式的運行比cpu=samples要慢很多,以下是採集數據日誌: 


這裏的count代表着該方法被真正執行了多少次,並且方法thread消耗了多少精確的cpu 時間。

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