作者:朝雨憶輕塵
來源:www.cnblogs.com/xifengxiaoma/p/9402497.html
JVisualVM 簡介
VisualVM 是Netbeans的profile子專案,已在JDK6.0 update 7 中自帶,能夠監控執行緒,記憶體情況,查看方法的CPU時間和記憶體中的對 象,已被GC的物件,反向查看分配的堆疊(如100個String物件分別由哪幾個物件分配出來的),在JDK_HOME/bin(默認是C:\Program Files\Java\jdk1.6.0_13\bin)目錄下面,有一個jvisualvm.exe檔案,雙擊打開,從UI上來看,這個軟體是基于NetBeans開發的了,
VisualVM 提供了一個可視界面,用于查看 Java 虛擬機 (Java Virtual Machine, JVM) 上運行的基于 Java 技術的應用程式的詳細資訊,VisualVM 對 Java Development Kit (JDK) 工具所檢索的 JVM 軟體相關資料進行組織,并通過一種使您可以快速查看有關多個 Java 應用程式的資料的方式提供該資訊,
您可以查看本地應用程式或遠程主機上運行的應用程式的相關資料,此外,還可以捕獲有關 JVM 軟體實體的資料,并將該資料保存到本地系統,以供后期查看或與其他用戶共享,
雙擊啟動 jvisualvm.exe,啟動起來后和jconsole 一樣同樣可以選擇本地和遠程,如果需要監控遠程同樣需要配置相關引數,
主界面如下:

VisualVM可以根據需要安裝不同的插件,每個插件的關注點都不同,有的主要監控GC,有的主要監控記憶體,有的監控執行緒等,

如何安裝:
1、從主選單中選擇“工具”>“插件”,
2、在“可用插件”標簽中,選中該插件的“安裝”復選框,單擊“安裝”,
3、逐步完成插件安裝程式,
我這里以 Eclipse(pid 22296)為例,雙擊后直接展開,主界面展示了系統和jvm兩大塊內容,點擊右下方jvm引數和系統屬性可以參考詳細的引數資訊.

因為VisualVM的插件太多,我這里主要介紹三個我主要使用幾個:監控、執行緒、Visual GC
監控的主頁其實也就是,cpu、記憶體、類、執行緒的圖表

執行緒和jconsole功能沒有太大的區別

Visual GC 是常常使用的一個功能,可以明顯的看到年輕代、老年代的記憶體變化,以及gc頻率、gc的時間等,

以上的功能其實jconsole幾乎也有,VisualVM更全面更直觀一些,另外VisualVM非常多的其它功能,可以分析dump的記憶體快照,
dump出來的執行緒快照并且進行分析等,還有其它很多的插件大家可以去探索

準備模擬記憶體泄漏樣例
1、定義靜態變數HashMap
2、分段回圈創建物件,并加入HashMap
代碼如下:
import java.util.HashMap;
import java.util.Map;
public class CyclicDependencies {
//宣告快取物件
private static final Map map = new HashMap();
public static void main(String args[]){
try {
Thread.sleep(10000);//給打開visualvm時間
} catch (InterruptedException e) {
e.printStackTrace();
}
//回圈添加物件到快取
for(int i=0; i<1000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("first");
//為dump出堆提供時間
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<1000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("second");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<3000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("third");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<4000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("forth");
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("qqqq");
}
}
3、配置jvm引數如下:
-Xms512m
-Xmx512m
-XX:-UseGCOverheadLimit
-XX:MaxPermSize=50m
4、運行程式并打卡visualvm監控
使用JVisualVM分析記憶體泄漏
1、查看Visual GC標簽,內容如下,這是輸出first的截圖

這是輸出forth的截圖:

通過2張圖對比發現:


老生代一直在gc,當程式繼續運行可以發現老生代gc還在繼續:

增加到了7次,但是老生代的記憶體并沒有減少,說明存在無法被回收的物件,可能是記憶體泄漏了,
如何分析是那個物件泄漏了呢?打開抽樣器標簽:點擊后如下圖:

按照程式輸出進行堆dump,當輸出second時,dump一次,當輸出forth時dump一次,
進入最后dump出來的堆標簽,點擊類:

點擊右上角:“與另一個堆存盤對比”,如圖選擇第一次匯出的dump內容比較:

比較結果如下:

可以看出在兩次間隔時間內TestMemory物件實體一直在增加并且多了,說明該物件參考的方法可能存在記憶體泄漏,
如何查看物件參考關系呢?
右鍵選擇類TestMemory,選擇“在實體視圖中顯示”,如下所示:

左側是創建的實體總數,右側上部為該實體的結構,下面為參考說明,從圖中可以看出在類CyclicDependencies里面被參考了,并且被HashMap參考,
如此可以確定泄漏的位置,進而根據實際情況進行分析解決,
JVisualVM 遠程監控 Tomcat
1、修改遠程tomcat的catalina.sh組態檔,在其中增加:
-JAVA_OPTS="$JAVA_OPTS
-Djava.rmi.server.hostname=192.168.122.128
-Dcom.sun.management.jmxremote.port=18999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false"
這次配置先不走權限校驗,只是打開jmx埠,
打開jvisualvm,右鍵遠程,選擇添加遠程主機:

輸入主機的名稱,直接寫ip,如下:

右鍵新建的主機,選擇添加JMX連接,輸入在tomcat中配置的埠即可,
雙擊打開,完畢!
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2021最新版)
2.終于靠開源專案弄到 IntelliJ IDEA 激活碼了,真香!
3.阿里 Mock 工具正式開源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式發布,全新顛覆性版本!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/290546.html
標籤:Java
