有了這款可視化工具,Java 應用性能調優 so easy。。。

  • JVisualVM 簡介
  • 案例分析
    • 準備模擬內存泄漏樣例
    • 使用JVisualVM分析內存泄漏
    • JVisualVM 遠程監控 Tomcat

JVisualVM 簡介html

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開發的了。java

VisualVM 提供了一個可視界面,用於查看 Java 虛擬機 (Java Virtual Machine, JVM) 上運行的基於 Java 技術的應用程序的詳細信息。
VisualVM 對 Java Development Kit (JDK) 工具所檢索的 JVM 軟件相關數據進行組織,並經過一種使您能夠快速查看有關多個 Java 應用程序的數據的方式提供該信息。您能夠查看本地應用程序或遠程主機上運行的應用程序的相關數據。此外,還能夠捕獲有關 JVM 軟件實例的數據,並將該數據保存到本地系統,以供後期查看或與其餘用戶共享。緩存

雙擊啓動 jvisualvm.exe,啓動起來後和jconsole 同樣一樣能夠選擇本地和遠程,若是須要監控遠程一樣須要配置相關參數。tomcat

主界面以下;
在這裏插入圖片描述
VisualVM能夠根據須要安裝不一樣的插件,每一個插件的關注點都不一樣,有的主要監控GC,有的主要監控內存,有的監控線程等。
在這裏插入圖片描述
如何安裝:微信

一、從主菜單中選擇「工具」>「插件」。二、在「可用插件」標籤中,選中該插件的「安裝」複選框。單擊「安裝」。三、逐步完成插件安裝程序。機器學習

我這裏以 Eclipse(pid 22296)爲例,雙擊後直接展開,主界面展現了系統和jvm兩大塊內容,點擊右下方jvm參數和系統屬性能夠參考詳細的參數信息.
在這裏插入圖片描述
由於VisualVM的插件太多,我這裏主要介紹三個我主要使用幾個:監控、線程、Visual GC
監控的主頁其實也就是,cpu、內存、類、線程的圖表
在這裏插入圖片描述
線程和jconsole功能沒有太大的區別
在這裏插入圖片描述
Visual GC 是經常使用的一個功能,能夠明顯的看到年輕代、老年代的內存變化,以及gc頻率、gc的時間等。
在這裏插入圖片描述
以上的功能其實jconsole幾乎也有,VisualVM更全面更直觀一些,另外VisualVM很是多的其它功能,能夠分析dump的內存快照,
dump出來的線程快照而且進行分析等,還有其它不少的插件你們能夠去探索
在這裏插入圖片描述
案例分析jvm

準備模擬內存泄漏樣例工具

一、定義靜態變量HashMap
二、分段循環建立對象,並加入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");
    }
}

三、配置jvm參數以下:大數據

-Xms512m
         -Xmx512m
         -XX:-UseGCOverheadLimit
         -XX:MaxPermSize=50m

四、運行程序並打卡visualvm監控

使用JVisualVM分析內存泄漏

一、查看Visual GC標籤,內容以下,這是輸出first的截圖
在這裏插入圖片描述
這是輸出forth的截圖:
在這裏插入圖片描述
經過2張圖對比發現:
在這裏插入圖片描述
在這裏插入圖片描述
老生代一直在gc,當程序繼續運行能夠發現老生代gc還在繼續:
在這裏插入圖片描述
增長到了7次,可是老生代的內存並無減小。說明存在沒法被回收的對象,多是內存泄漏了。
如何分析是那個對象泄漏了呢?打開抽樣器標籤:點擊後以下圖:
在這裏插入圖片描述
按照程序輸出進行堆dump,當輸出second時,dump一次,當輸出forth時dump一次。
進入最後dump出來的堆標籤,點擊類:
在這裏插入圖片描述
點擊右上角:「與另外一個堆存儲對比」。如圖選擇第一次導出的dump內容比較:
在這裏插入圖片描述
比較結果以下:
在這裏插入圖片描述
能夠看出在兩次間隔時間內TestMemory對象實例一直在增長而且多了,說明該對象引用的方法可能存在內存泄漏。
如何查看對象引用關係呢?
右鍵選擇類TestMemory,選擇「在實例視圖中顯示」,以下所示:
在這裏插入圖片描述
左側是建立的實例總數,右側上部爲該實例的結構,下面爲引用說明,從圖中能夠看出在類CyclicDependencies裏面被引用了,而且被HashMap引用。

如此能夠肯定泄漏的位置,進而根據實際狀況進行分析解決。

JVisualVM 遠程監控 Tomcat

一、修改遠程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中配置的端口便可。

四、雙擊打開。完畢!

參考資料

http://www.javashuo.com/article/p-zcrjomcc-dv.html
http://www.javashuo.com/article/p-wjpnpydd-q.html

來源:朝雨憶輕塵
cnblogs.com/xifengxiaoma/p/9402497.html
在這裏插入圖片描述 歡迎關注個人微信公衆號「碼農突圍」,分享Python、Java、大數據、機器學習、人工智能等技術,關注碼農技術提高•職場突圍•思惟躍遷,20萬+碼農成長充電第一站,陪有夢想的你一塊兒成長

相關文章
相關標籤/搜索