VisualVM:多合一故障處理工具

   VisualVM(All-in-One Java Troubleshooting Tool)是到目前爲止隨JDK發佈的功能最強大的運行監視和故障處理程序,而且能夠碰見在將來一段時間內都是官方主力發展的虛擬機故障處理工具。官方在VisualVM的軟件說明中寫上了「All-in-One」的描述字樣,預示着他除了運行監視、故障處理外,還提供了不少其餘方面的功能。如性能分析(Profiling),VisualVM的性能分析功能甚至比起JProfiler、YourKit等專業且收費的Profiling工具都不會遜色多少,並且VisualVM還有一個很大的優勢:不須要被監視的程序基於特殊Agent運行,所以他對應用程序的實際性能的影響很小,使得他能夠直接應用在生產環境中。這個優勢是JProfiler、YourKit等工具沒法與之媲美的。網絡

VisualVM兼容範圍與插件安裝

        VisualVM基於NetBeans平臺開發,所以他一開始就具有了插件擴展功能的特性,經過插件擴展支持,VisualVM能夠作到:多線程

  • 顯示虛擬機進程以及進程的配置、環境信息(jps、jinfo)。
  • 監視應用程序的CPU、GC、堆、方法區以及線程的信息(jstat、jstack)。
  • dump以及分析堆轉儲快照(jmap、jhat)。
  • 方法級的程序運行性能分析,找到被調用最多、運行時間最長的方法。
  • 離線程序快照:收集程序的運行時配置、線程dump、內存dump等信息創建一個快照,能夠將快照發送開發者處進行Bug反饋。
  • 其餘plugins的無限的可能性......

        VisualVM在JDK 1.6 update 7中才首次出現,但並不意味着他只能監控運行於JDK 1.6上的程序,他具有很強的向下兼容能力,甚至能向下兼容至近10年前發佈的JDK 1.4.2平臺,這對無數已經處於實施、維護的項目頗有意義。固然,並不是全部功能都能完美的向下兼容。dom

        首次啓動VisualVM後,沒必要着急找應用程序進行檢測,由於如今VisualVM尚未加載任何插件,雖然基本的監視、線程面板的功能都以默認插件的形式提供了,可是不給VisualVM裝任何擴展插件,就至關於放棄了他最精華的功能,和沒有安裝任何應用軟件操做系統差很少。工具

        插件能夠進行手工安裝,在相關網站上下載*.nbm包後,點擊「工具」→「插件」→「已下載」菜單,而後在彈出的對話框中指定nbm包路徑即可進行安裝,插件按照後存放在JDK_HOME/lib/visumalvm/visualvm中。不過手工安裝並不經常使用,使用VisualVM的自動安裝功能已經能夠找到大多數所需的插件,在有網絡鏈接的環境下,點擊「工具」→「插件菜單」,彈出下圖所示的插件頁面,在頁籤的「可用插件」中列舉了當前版本VisualVM可使用的插件,選中插件後在右邊窗口將顯示這個插件的基本信息,如開發者、版本、功能描述等。性能

        你們能夠根據本身的工做須要和興趣選擇合適的插件,而後點擊安裝按鈕,彈出以下圖所示的下載進度窗口,跟着提示操做便可完成安裝。優化

         安裝完插件,選擇一個須要監視的程序就進入程序的主界面了,以下圖所示。根據選擇安裝插件數量的不一樣,看到的頁籤可能和下圖中的有所不一樣。網站

        VisualVM中「概述」、「監視」、「線程」、「MBeans」的功能與JConsole差異不大,在此不作贅述,下面挑選幾個特點功能、插件進行介紹。spa

生成瀏覽堆轉儲快照

        在VisualVM中生成dump文件有兩種方式,能夠執行下列任一操做:操作系統

  • 在「應用程序」窗口中右鍵點擊應用程序節點,而後選擇「堆Dump」。
  • 在「應用程序」窗口中雙擊應用程序節點以打開應用程序標籤,而後在「監視」標籤中單機「堆Dump」。

        生成了dump文件以後,應用程序頁籤將在該堆的應用程序下增長一個以[heapdump]開頭的子節點,而且在主頁籤中打開了該轉儲快照,以下圖所示。若是須要把dump文件保存或發送出去,要在heapdump節點上右鍵選擇「另存爲」菜單,不然當VisualVM關閉時,生成的dump文件會被看成臨時文件刪除掉。要打開一個已經存在的dump文件,經過文件菜單中的「裝入」功能,選擇硬盤的dump文件便可。.net

        從堆頁籤中的「摘要」面板能夠看到應用程序dump時的運行時參數、System.getProperties()的內容、線程堆棧等信息,「類」面板則是以類爲統計口徑統計類的實例數量、容量信息,「實例」面板不能直接使用,由於不能肯定用戶想查看哪一個類的實例,因此須要經過「類」面板進入,在「類」中選擇一個關心的類後雙擊鼠標,便可在「實例」裏面看見此類中500個實例的具體屬性信息。「OQL控制檯」面板中就是運行OQL查詢語句的。

分析程序性能

        在Profiler頁籤中,VisualVM提供了程序運行期間方法級的CPU執行時間分析以及內存分析,作Profiling分析確定會對程序運行性能有比較大的影響,因此通常不在生產環境中使用這項功能。

        要開始分析,先選擇「CPU」和「內存」按鈕中的一個,而後切換到應用程序中對程序進行操做,VisualVM會記錄到這段時間中應用程序執行過的方法。若是是CPU分析,將會統計每一個方法的執行次數、執行耗時;若是是內存分析,則會統計每一個方法關聯的對象數以及這些對象所佔的空間。分析結束後,點擊「中止」按鈕結束監控過程,以下圖所示。

        注意,在JDK 1.5以後,在Client模式下的虛擬機加入而且自動開啓了類共享——這是一個在多虛擬機進程中共享rt.jar中類數據以提升加載速度和節省內存的優化,而根據相關Bug報告的反映,VisualVM的Profiler功能可能會由於類共享而致使被監視的應用程序崩潰,因此進行Profiling前,最好在被監視程序中使用-Xshare : off參數來關閉類共享優化。

        上圖是對Eclipse IDE一段操做的錄製和分析結果,分析本身的應用程序時,能夠根據實際業務的複雜與方法的時間、調用次數作比較,找到最有優化價值的方法。

BTrace動態日誌追蹤

        BTrace是一個很「有趣」的VisualVM插件,自己也是能夠獨立運行的程序。他的做用是在不中止目標程序運行的前提下,經過HotSpot虛擬機的HotSwap技術(代碼熱替換技術,HotSpot虛擬機容許在不中止運行的狀況下,更新已經加載的類的代碼)動態加入本來並不存在的調試代碼。這項功能對實際生產中的程序頗有意義:常常遇到程序出現問題,但排查錯誤的一些必要信息,譬如方法參數、返回值等,在開發時並無打印到日誌之中,以致於不得不停掉服務,經過調試增量來加入日誌代碼以解決問題。當遇到生產環境沒法隨便中止時,缺一兩句日誌致使排錯進行不下去是一件很是鬱悶的事情。

        在VisualVM中安裝了BTrace插件後,在應用程序面板中右鍵點擊要調試的程序,會出現「Trace Application......」菜單,點擊將進入BTrace面板。這個面板裏面看起來就像一個簡單地Java程序開發環境,裏面還有一小段Java代碼,以下圖所示。

        這裏準備了一段很簡單的Java代碼來演示BTrace的功能:產生兩個1000之內的隨機整數,輸出這兩個數字相加的結果,以下面所示。

public class BTraceTest {

    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) throws IOException {
        BTraceTest test = new BTraceTest();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 0; i < 10; i++) {
            reader.readLine();
            int a = (int) Math.round(Math.random() * 1000);
            int b = (int) Math.round(Math.random() * 1000);
            System.out.println(test.add(a, b));
        }
    }
}

        程序運行後,在VisualVM中打開該程序的監視,在BTrace頁籤填充TracingScript的內容,輸入的調試代碼以下所示。

/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
    @OnMethod(
    clazz="org.fenixsoft.monitoring.BTraceTest",
    method="add",
    location=@Location(Kind.RETURN)
)

public static void func(@Self org.fenixsoft.monitoring.BTraceTest instance,int a,int b,@Return int result) {
    println("調用堆棧:");
    jstack();
    println(strcat("方法參數A:",str(a)));
    println(strcat("方法參數B:",str(b)));
    println(strcat("方法結果:",str(result)));
}
}

        點擊「Start」按鈕後稍等片刻,編譯完成後,可見Output面板中出現「BTrace code successfuly deployed」的字樣。程序運行的時候在Output面板將會輸出下圖所示的調試信息。

        BTrace的用法還有不少,打印調用堆棧、參數、返回值只是最基本的應用,在他的網站上使用BTrace進行性能監視、定位鏈接泄漏和內存泄漏、解決多線程競爭問題等例子。

參考文獻:《深刻理解Java虛擬機》

https://blog.csdn.net/en_joker/article/details/79812226

相關文章
相關標籤/搜索