在前面已經學習了JVM性能監控的命令列工具,接下來學習JVM性能監控的命令列工具,通過可視化工具可以更直觀地監控JVM性能、處理JVM相關問題,
1、JConsole
JConsole( Java Monitoring and Management Console),是一款基于 JMX( Java Manage-ment Extensions) 的可視化監視管理工具,
它的功能主要是對系統進行收集和引數調整,不僅可以用在虛擬機本身的管理上,還可以用于運行于虛擬機之上的軟體中,
1.1、JConsole連接Java程式
JConsole程式位于%JAVA_HOME%bin目錄下,直接通過命令啟動,

在新建連接對話框中,羅列了所有的本地Java應用程式,選擇需要連接的程式即可,
下面還有一個用于連接遠程行程的文本框,輸入正確的遠程地址即可連接,
如果一個程式需要使用JConsole與那成連接,則需要在啟動Java程式時,加上以下引數:
JAVA_OPTS="-Dfile.encoding=UTF-8"
JAVA_OPTS="$JAVA_OPTS -Dlog.dir=$LOG_PATH"
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=xxx.xxx.xxx.xxx(本機IP) -Dcom.sun.management.jmxremote"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=xx"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
1.2、Java程式概況
使用JConsole連接了一個本地程式,在概述可以看到Java程式運行的概覽資訊,包括堆記憶體使用情況、執行緒、類、CPU使用情況四項資訊的曲線圖,

1.3、記憶體監控
記憶體的作用相當于可視化的jstat命令,用于監視被收集器管理的虛擬機記憶體,
它不僅包含堆記憶體的整體資訊,更細化到eden區、suvivior區、老年代的使用情況,

為了更加清晰地查看記憶體地變化,運行下面一段程式,然后連接:
/**
* VM引數: -Xms100m -Xmx100m -XX:+UseSerialGC
*/
public class JConcoleRAMMonitor {
/***
* 記憶體占位符物件,一個OOMObject大約占64KB
*/
static class OOMObject {
public byte[] placeholder = new byte[64 * 1024];
}
public static void fillHeap(int num) throws InterruptedException {
List<OOMObject> list = new ArrayList<OOMObject>();
for (int i = 0; i < num; i++) {
// 稍作延時,令監視曲線的變化更加明顯
Thread.sleep(300);
list.add(new OOMObject());
}
System.gc();
}
public static void main(String[] args) throws Exception {
fillHeap(2000);
}
}
這段代碼的作用是以64KB/50ms的速度向Java堆中填充資料,一共填充1000次,
觀察Eden區的運行趨勢,發現呈折線,觀察堆記憶體使用,發現以稍有曲折的狀態向上增長,

執行System.gc()之后,老年代的柱狀圖仍然顯示峰值狀態,最后程式會以堆記憶體溢位結束,這是因為空間未能回收——List<OOMObject>list物件一直存活, fillHeap()方法仍然沒有退出,如果把 System.gc()移動到fillHeap()方法外呼叫就可以回收掉全部記憶體,
1.4、執行緒監控
JConcole還可以監控執行緒,相當于可視化的jstack命令,如圖,JConcole顯示了系統內的執行緒數量,并在螢屏下方顯示了程式中所有的執行緒,單擊執行緒名稱,就可以查看執行緒的堆疊資訊,

使用JConsole還可以快速定位死鎖問題,
這是一段會產生死鎖的代碼:
public class ThreadLockDemo {
/**
* 執行緒死鎖等待演示
*/
static class SynAddRunalbe implements Runnable {
int a, b;
public SynAddRunalbe(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (Integer.valueOf(a)) {
synchronized (Integer.valueOf(b)) {
System.out.println(a + b);
}
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new SynAddRunalbe(1, 2)).start();
new Thread(new SynAddRunalbe(2, 1)).start();
}
}
}
出現執行緒死鎖以后,點擊JConsole執行緒面板的檢測到死鎖按鈕,將會看到執行緒的死鎖資訊,

可以看到執行緒Thread-199等待執行緒Thread-21持有的資源,
1.5、類加載情況
如圖,類頁面顯示了已經裝載的類數量,在詳細資訊欄中,還顯示了已經卸載的類的數量,

1.6、虛擬機資訊
在VM摘要,JConsole顯示了當前應用程式的運行環境,包括虛擬機型別、版本、堆資訊以及虛擬機引數等,

2、VisualVM
VisualVM(All-in-One Java Troubleshooting Tool)是功能最強大的運行監視和故障處理程式之一,曾經在很長一段時間內是Oracle官方主力發展的虛擬機故障處理工具,
相比一些第三方工具,VisualVM有一個很大的優點:不需要被監視的程式基于特殊Agent去運行,因此它的通用性很強,對應用程式實際性能的影響也較小,使得它可以直接應用在生產環境中,
2.1、VisualVM安裝插件
在JDK6 Update7以后,VisualVM便作為JDK的一部分發布,它在%JAVA_HOME%bin 目錄下,點擊就可以啟動,

VisualVM的精華之處在于它的插件,插件安裝可以手動安裝或者自動安裝,
手動安裝,從地址 https://visualvm.github.io/pluginscenters.html 下載載nbm包,點擊“工具->插件->已下載”選單,然后在彈出對話框中指定nbm包路徑便可完成安裝,
一般選擇自動安裝,點擊工具-> 插件選單,在可用插件里可以看到可安裝的插件,按需安裝即可,

VisualVM中概述,監視、執行緒,MBeans的功能與前面介紹的JConsole差別不大,這里就不在贅言,
2.2、生成、瀏覽堆轉儲快照
在VisualVM中生成堆轉儲快照檔案有兩種方式,可以執行下列任一操作:
- 在
應用程式視窗中右鍵單擊應用程式節點,然后選擇堆Dump, - 在
應用程式視窗中雙擊應用程式節點以打開應用程式標簽,然后在“監視”標簽中單擊堆Dump,

生成堆轉儲快照檔案之后,該堆的應用程式下增加了一個以[heap-dump]開頭的子節點,如果需要把堆轉儲快照保存或發送出去,就需要heapdump節點上右鍵選擇“另存為”選單,否則當VisualVM關閉時,生成的堆轉儲快照檔案會被當作臨時檔案自動清理掉,要打開一個由已經存在的堆轉儲快照檔案,通過檔案選單中的“裝入”功能,選擇磁盤上的檔案即可,

2.3、分析程式性能
要開始性能分析,先選擇“CPU”和“記憶體”按鈕中的一個,然后切換到應用程式中對程式進行操作,VisualVM會記錄這段時間中應用程式執行過的所有方法,

如果是進行處理器執行時間分析,將會統計每個方法的執行次數、執行耗時;

如果是記憶體分析,則會統計每個方法關聯的物件數以及這些物件所占的空間,

等要分析的操作執行結束后,點擊“停止”按鈕結束監控程序,
2.4、BTrace動態日志跟蹤
BTrace是個很有意思的插件,它可以在不停機的情況下,通過位元組碼注入動態監控系統的運行情況,
Btrace自動安裝如下,到github的網路可能存在不穩定的問題,可以重試,或者手動安裝

在VisualVM中安裝了BTrace插件后,在應用程式面板中右擊要除錯的程式,會出現“Trace Application…”選單:

點擊將進入BTrace面板,這個面板看起來就像一個簡單的Java程式開發環境:

現在來嘗試使用BTrace追蹤正在運行的程式,
一段簡單的Java代碼:產生兩個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 = "cn.fighter3.test.BTraceTest",
method = "add",
location = @Location(Kind.RETURN)
)
public static void func(@Self cn.fighter3.test.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的用途很廣泛,列印呼叫堆疊、引數、回傳值只是它最基礎的使用形式,更多應用可以查看官方倉庫 https://github.com/btraceio/btrace/wiki ,
3、Java Mission Control
JMV最初是JRockit虛擬機提供的一款診斷工具,在Oracle JDK7 Update 40以后,它就系結在Oracle JDK中發布,
JMC位置是%JAVA_HOME%/bin/jmc.exe,打開軟體界面:

在左側的“JVM瀏覽器”面板中自動顯示了通過JDP協議(Java Discovery Protocol)找到的本機正在運行的HotSpot虛擬機行程,
3.1、MBean服務器
點擊本地行程的MBean服務器:

可以看到,以飛行儀表的視圖顯示了Java堆使用率,CPU使用率和Live Set+Fragmentation,
3.2、飛行記錄器(Flight Recorder)
飛行記錄器是JMC提供的另一大功能,它通過記錄程式在一段時間內的運行情況,將記錄結果進行分析和展示,可以更進一步對系統的性能進行分析和診斷,
要使用JFR,程式啟動需要帶以下引數:
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder
連接加了相關引數啟動的程式,啟動飛行記錄,進行一分鐘的性能記錄:

記錄結束后,JMC會自動打開剛才的記錄:

JFR提供的資料質量通常也要比其他工具通過代理形式采樣獲得或者從MBean中取得的資料高得多,以垃圾搜集為例,HotSpot的MBean中一般有各個分代大小、收集次數、時間、占用率等資料(根據收集器不同有所差別),這些都屬于“結果”類的資訊,而JFR中還可以看到記憶體中這段時間分配了哪些物件、哪些在TLAB中(或外部)分配、分配速率 和壓力大小如何、分配歸屬的執行緒、收集時物件分代晉升的情況等,
4、第三方工具
以上三個都是JDK自帶的性能監控工具,除此之外還有一些第三方的性能監控工具,
- MAT
Java 堆記憶體分析工具,
- GChisto
GC 日志分析工具,
- GCViewer
GC 日志分析工具,
- JProfiler
商用的性能分析利器,
- arthas
阿里開源診斷工具,
- async-profiler
Java 應用性能分析工具,開源、火焰圖、跨平臺,
這里只是簡單羅列,就不再展開詳細介紹,
參考:
【1】:周志明編著《深入理解Java虛擬機:JVM高級特性與最佳實踐》
【2】:《實戰JAVA虛擬機 JVM故障診斷與性能優化》
【3】:Jvm 系列(七):Jvm 調優-工具篇
【4】:給,你們想要的排查問題的可視化工具
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/274443.html
標籤:其他
