天天看點

這款 Java 性能調優工具,真的很強!

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 一樣同樣可以選擇本地和遠端,如果需要監控遠端同樣需要配置相關參數。

主界面如下:

這款 Java 性能調優工具,真的很強!
VisualVM可以根據需要安裝不同的插件,每個插件的關注點都不同,有的主要監控GC,有的主要監控記憶體,有的監控線程等。
這款 Java 性能調優工具,真的很強!

如何安裝:

1、從主菜單中選擇“工具”>“插件”。

2、在“可用插件”标簽中,選中該插件的“安裝”複選框。單擊“安裝”。

3、逐漸完成插件安裝程式。

我這裡以 Eclipse(pid 22296)為例,輕按兩下後直接展開,主界面展示了系統和jvm兩大塊内容,點選右下方jvm參數和系統屬性可以參考詳細的參數資訊.

這款 Java 性能調優工具,真的很強!

因為VisualVM的插件太多,我這裡主要介紹三個我主要使用幾個:監控、線程、Visual GC

監控的首頁其實也就是,cpu、記憶體、類、線程的圖表

這款 Java 性能調優工具,真的很強!
線程和jconsole功能沒有太大的差別
這款 Java 性能調優工具,真的很強!
Visual GC 是常常使用的一個功能,可以明顯的看到年輕代、老年代的記憶體變化,以及gc頻率、gc的時間等。
這款 Java 性能調優工具,真的很強!

以上的功能其實jconsole幾乎也有,VisualVM更全面更直覺一些,另外VisualVM非常多的其它功能,可以分析dump的記憶體快照,

dump出來的線程快照并且進行分析等,還有其它很多的插件大家可以去探索

這款 Java 性能調優工具,真的很強!

準備模拟記憶體洩漏樣例

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的截圖

這款 Java 性能調優工具,真的很強!

這是輸出forth的截圖:

這款 Java 性能調優工具,真的很強!

通過2張圖對比發現:

這款 Java 性能調優工具,真的很強!

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

這款 Java 性能調優工具,真的很強!

增加到了7次,但是老生代的記憶體并沒有減少。說明存在無法被回收的對象,可能是記憶體洩漏了。

如何分析是那個對象洩漏了呢?打開抽樣器标簽:點選後如下圖:

這款 Java 性能調優工具,真的很強!

按照程式輸出進行堆dump,當輸出second時,dump一次,當輸出forth時dump一次。

進入最後dump出來的堆标簽,點選類:

這款 Java 性能調優工具,真的很強!

點選右上角:“與另一個堆存儲對比”。如圖選擇第一次導出的dump内容比較:

這款 Java 性能調優工具,真的很強!

比較結果如下:

這款 Java 性能調優工具,真的很強!

可以看出在兩次間隔時間内TestMemory對象執行個體一直在增加并且多了,說明該對象引用的方法可能存在記憶體洩漏。

如何檢視對象引用關系呢?

右鍵選擇類TestMemory,選擇“在執行個體視圖中顯示”,如下所示:

這款 Java 性能調優工具,真的很強!

左側是建立的執行個體總數,右側上部為該執行個體的結構,下面為引用說明,從圖中可以看出在類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,右鍵遠端,選擇添加遠端主機:

這款 Java 性能調優工具,真的很強!

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

這款 Java 性能調優工具,真的很強!

右鍵建立的主機,選擇添加JMX連接配接,輸入在tomcat中配置的端口即可。

輕按兩下打開。完畢!

繼續閱讀