Java VisualVM默認沒有安裝Visual GC插件,需要手動安裝,JDK的安裝目錄的bin目露下雙擊jvisualvm.exe,即可打開Java VisualVM,點擊菜單欄 工具->插件 安裝Visual GC
安裝完成后重啟Java VisualVM,Visual GC界面自動打開,即可看到JVM中堆內存的分代情況
被監控的程序運行一段時間后Visual GC顯示如下
一:整個區域分為三部分:spaces、graphs、histogram
1,spaces區域:代表虛擬機內存分布情況。從圖中可以看出,虛擬機被分為Perm、Old、Eden、S0、S1
注意:如果對每個區域基本概念不是很熟悉的可以先了解下java虛擬機運行時數據區這篇文字。
1.1)perm:英文叫做Permanent Generation,我們稱之為永久代。(根據深入java虛擬機作者說明,這里說法不是不是很正確,因為hotspot虛擬機的設計團隊選擇把GC分代收集擴展至此而已,正確的應該叫做方法區或者非堆)。
1.1.1)通過VM Args:-XX:PermSize=128m -XX:MaxPermSize=256m 設置初始值與最大值
1.2)heap:java堆(Java heap)。它包括老年代(圖中Old區域)和新生代(圖中Eden/S0/S1三個統稱新生代,分為Eden區和兩個Survivor區域),他們默認是8:1分配內存
1.2.1)通過VM Args:-xms512m -Xmx512m -XX:+HeapDumpOnOutofMemoryError -Xmn100m -XX:SurvivorRatio=8 設置初始堆內存、最大堆內存、內存異常打印dump、新生代內存、新生代內存分配比例(8:1:1),因為Heap分為新生代跟老年代,所以512M-100M=412M,老年代就是412M(初始內存跟最大內存最好相等,防止內存不夠時擴充內存或者Full GC,導致性能降低)
2,Graphs區域:內存使用詳細介紹
2.1)Compile Time(編譯時間):6368compiles 表示編譯總數,4.407s表示編譯累計時間。一個脈沖表示一次JIT編譯,窄脈沖表示持續時間短,寬脈沖表示持續時間長。
2.2)Class Loader Time(類加載時間): 20869loaded表示加載類數量, 139 unloaded表示卸載的類數量,40.630s表示類加載花費的時間
2.3)GC Time(GC Time):2392collections表示垃圾收集的總次數,37.454s表示垃圾收集花費的時間,last cause表示最近垃圾收集的原因
2.4)Eden Space(Eden 區):括號內的31.500M表示最大容量,9.750M表示當前容量,后面的4.362M表示當前使用情況,2313collections表示垃圾收集次數,8.458s表示垃圾收集花費時間
2.5)Survivor 0/Survivor 1(S0和S1區):括號內的3.938M表示最大容量,1.188M表示當前容量,之后的值是當前使用情況
2.6)Old Gen(老年代):括號內的472.625M表示最大容量,145.031M表示當前容量,之后的87.031表示當前使用情況,79collections表示垃圾收集次數 ,28.996s表示垃圾收集花費時間
2.7)Perm Gen(永久代):括號內的256.000M表示最大容量,105.250M表示當前容量,之后的105.032M表示當前使用情況
3,Histogram區域:survivor區域參數跟年齡柱狀圖
3.1)Tenuring Threshold:表示新生代年齡大於當前值則進入老年代
3.2)Max Tenuring Threshold:表示新生代最大年齡值。
3.3)Tenuring Threshold與Max Tenuring Threshold區別:Max Tenuring Threshold是一個最大限定,所有的新生代年齡都不能超過當前值,而Tenuring Threshold是個動態計算出來的臨時值,一般情況與Max Tenuring Threshold相等,如果在Suivivor空間中,相同年齡所有對象大小的總和大於Survivor空間的一半,則年齡大於或者等於該年齡的對象就都可以直接進入老年代(如果計算出來年齡段是5,則Tenuring Threshold=5,age>=5的Suivivor對象都符合要求),它才是新生代是否進入老年代判斷的依據。
3.4)Desired Survivor Size:Survivor空間大小驗證闕值(默認是survivor空間的一半),用於Tenuring Threshold判斷對象是否提前進入老年代。
3.5)Current Survivor Size:當前survivor空間大小
3.6)histogram柱狀圖:表示年齡段對象的存儲柱狀圖
3.7)如果顯示指定-XX:+UseParallelGC --新生代並行、老年代串行收集器 ,則histogram柱狀圖不支持當前收集器
內存溢出( out of memory),是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
內存泄露 (memory leak),是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。其實說白了就是該內存空間使用完畢之后未回收。
二 Java VisualVM的其他功能
1.監視界面(cpu,類,堆,線程)
2.線程界面
VisualVM 的線程標簽提供了三種視圖,默認會以時間線的方式展現。另外兩種視圖分別是表視圖和詳細信息視圖。
時間線視圖上方的工具欄提供了縮小,放大和自適應三個按鈕,以及一個下拉框,我們可以選擇將所有線程、活動線程或者完成的線程顯示在視圖中。
3.Profile界面(性能剖析)
在 Profiler 標簽,點擊“CPU”按鈕啟動一個 CPU 性能分析會話 ,VisualVM 會檢測應用程序所有的被調用的方法。當進入一個方法時,線程會發出一個“method entry”的事件,當退出方法時同樣會發出一個“method exit”的事件,這些事件都包含了時間戳。然后 VisualVM 會把每個被調用方法的總的執行時間和調用的次數按照運行時長展示出來。
此外,我們也可以通過性能分析結果下方的方法名過濾器對分析結果進行過濾。
點擊內存按鈕執行內存分析查看類
4.快照功能
我們可以使用 VisualVM 的快照功能生成任意個性能分析快照並保存到本地來輔助我們進行性能分析。快照為捕獲應用程序性能分析數據提供了一個很便捷的方式因為快照一旦生成可以在任何時候離線打開和查看,也可以相互傳閱。
VisualVM 提供了兩種類型的快照:
-
Profiler 快照:當有一個性能分析會話(內存或者 CPU)正在進行時,我們可以通過性能分析結果工具欄的“快照”按鈕生成 Profiler 快照捕獲當時的性能分析數據。
-
應用程序快照:我們可以右鍵點擊左側 Applications 窗口中應用程序節點,選擇“應用程序快照”為生成一個應用程序快照。應用程序快照會收集某一時刻的堆轉儲,線程轉儲和 Profiler 快照,同時也會捕獲 JVM 的一些基本信息。
5.堆dump(轉儲)和線程dump(轉儲)操作
線程轉儲的生成與分析
VisualVM 能夠對正在運行的本地應用程序生成線程轉儲,把活動線程的堆棧蹤跡打印出來,幫助我們有效了解線程運行的情況,診斷死鎖、應用程序癱瘓等問題。
堆轉儲的生成與分析
VisualVM 能夠生成堆轉儲,統計某一特定時刻 JVM 中的對象信息,幫助我們分析對象的引用關系、是否有內存泄漏情況的發生等。
Dump文件是進程的內存鏡像,可以把程序的執行狀態通過調試器保存到dump文件中,堆dump的dump文件內容如下圖所示
當 VisualVM 統計完堆內對象數據后,會把堆轉儲信息顯示在新的堆轉儲標簽內,我們可以看到摘要、類、實例數等信息以及通過 OQL 【對象查詢語言是專門為ODMG(Object Database Management Group)對象模型制定的查詢語言】控制台執行查詢語句功能。
堆轉儲的摘要包括轉儲的文件大小、路徑等基本信息,運行的系統環境信息,也可以顯示所有的線程信息
從類視圖可以獲得各個類的實例數和占用堆大小數,分析出內存空間的使用情況,找出內存的瓶頸,避免內存的過度使用。
通過實例數視圖可以獲得每個實例內部各成員變量的值以及該實例被引用的位置。首先需要在類視圖選擇需要查看實例的類。
此外,還能對兩個堆轉儲文件進行比較。通過比較我們能夠分析出兩個時間點哪些對象被大量創建或銷毀。
線程轉儲和堆轉儲均可以另存成文件,以便進行離線分析。
參考:
https://www.ibm.com/developerworks/cn/java/j-lo-visualvm/
http://tianxingzhe.blog.51cto.com/3390077/1651384/
http://blog.csdn.net/xuelinmei_happy/article/details/51090115
http://www.cnblogs.com/linghu-java/p/5689227.html