jdk監控和故障處理工具

主要jdk診斷命令

jps (JVM Process Status): 類似 UNIX 的 ps 命令。用戶查看所有 Java 進程的啓動類、傳入參數和 Java 虛擬機參數等信息;----常用
jstat( JVM Statistics Monitoring Tool): 用於收集 HotSpot 虛擬機各方面的運行數據; ----常用
jinfo (Configuration Info for Java) : Configuration Info forJava,顯示虛擬機配置信息;
jmap (Memory Map for Java) :生成堆轉儲快照;----常用
jhat (JVM Heap Dump Browser ) : 用於分析 heapdump 文件,它會建立一個 HTTP/HTML 服務器,讓用戶可以在瀏覽器上查看分析結果;
jstack (Stack Trace for Java):生成虛擬機當前時刻的線程快照,線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合。

1、jps:查看所有 Java 進程
jps -l:輸出主類的全名,如果進程執行的是 Jar 包,輸出 Jar 路徑。
在這裏插入圖片描述
jps -v:輸出虛擬機每個進程啓動時 JVM 參數。
在這裏插入圖片描述
2、jstat: 監視虛擬機各種運行狀態信息
jstat(JVM Statistics Monitoring Tool) 使用於監視虛擬機各種運行狀態信息的命令行工具。 它可以顯示本地或者遠程(需要遠程主機提供 RMI 支持)虛擬機進程中的類信息、內存、垃圾收集、JIT 編譯等運行數據,在沒有 GUI,只提供了純文本控制檯環境的服務器上,它將是運行期間定位虛擬機性能問題的首選工具。

jstat 命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如 jstat -gc -h3 7936 1000 10表示分析進程 id 爲 31736 的 gc 情況,每隔 1000ms 打印一次記錄,打印 10 次停止,每 3 行後打印指標頭部。
在這裏插入圖片描述
常見的 option 如下:

  • jstat -class vmid :顯示 ClassLoader 的相關信息;
  • jstat -compiler vmid :顯示 JIT 編譯的相關信息;
  • jstat -gc vmid :顯示與 GC 相關的堆信息;
  • jstat -gccapacity vmid :顯示各個代的容量及使用情況;
  • jstat -gcnew vmid :顯示新生代信息;
  • jstat -gcnewcapcacity vmid :顯示新生代大小與使用情況;
  • jstat -gcold vmid :顯示老年代和永久代的信息;
  • jstat -gcoldcapacity vmid :顯示老年代的大小;
  • jstat -gcpermcapacity vmid :顯示永久代大小;
  • jstat -gcutil vmid :顯示垃圾收集信息;

3、jinfo: 實時地查看和調整虛擬機各項參數
jinfo vmid :輸出當前 jvm 進程的全部參數和系統屬性 (第一部分是系統的屬性,第二部分是 JVM 的參數)。
在這裏插入圖片描述
jinfo -flag name vmid :輸出對應名稱的參數的具體值。比如輸出 MaxHeapSize。

在這裏插入圖片描述
使用 jinfo 可以在不重啓虛擬機的情況下,可以動態的修改 jvm 的參數。尤其在線上的環境特別有用,請看下面的例子:
jinfo -flag [+|-]name vmid 開啓或者關閉對應名稱的參數。
在這裏插入圖片描述
4、jmap:生成堆轉儲快照
jmap(Memory Map for Java)命令用於生成堆轉儲快照。 如果不使用 jmap 命令,要想獲取 Java 堆轉儲,可以使用 “-XX:+HeapDumpOnOutOfMemoryError” 參數,可以讓虛擬機在 OOM 異常出現之後自動生成 dump 文件,Linux 命令下可以通過 kill -3 發送進程退出信號也能拿到 dump 文件。

jmap 的作用並不僅僅是爲了獲取 dump 文件,它還可以查詢 finalizer 執行隊列、Java 堆和永久代的詳細信息,如空間使用率、當前使用的是哪種收集器等。和jinfo一樣,jmap有不少功能在 Windows 平臺下也是受限制的。

示例:將指定應用程序的堆快照輸出到D盤。後面,可以通過 jhat、Visual VM 等工具分析該堆文件。

C:\jdk8_4\bin>jmap -dump:format=b,file=D:test.hprof 7936
Dumping heap to D:\test.hprof ...
Heap dump file created

5、jstack :生成虛擬機當前時刻的線程快照
jstack(Stack Trace for Java)命令用於生成虛擬機當前時刻的線程快照。線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合.

生成線程快照的目的主要是定位線程長時間出現停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等都是導致線程長時間停頓的原因。線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在後臺做些什麼事情,或者在等待些什麼資源。
下面是一個線程死鎖的代碼。我們下面會通過 jstack 命令進行死鎖檢查,輸出死鎖信息,找到發生死鎖的線程。

public class DeadLockDemo {
    private static Object resource1 = new Object();//資源 1
    private static Object resource2 = new Object();//資源 2

    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource2");
                    synchronized (resource2) {
                        System.out.println(Thread.currentThread() + "get resource2");
                    }
                }
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource1");
                    synchronized (resource1) {
                        System.out.println(Thread.currentThread() + "get resource1");
                    }
                }
            }
        }.start();
    }
}

Output

Thread[Thread-1,5,main]get resource2
Thread[Thread-0,5,main]get resource1
Thread[Thread-1,5,main]waiting get resource1
Thread[Thread-0,5,main]waiting get resource2

爲什麼死鎖:線程 A 通過 synchronized (resource1) 獲得 resource1 的監視器鎖,然後通過Thread.sleep(1000);讓線程 A 休眠 1s 爲的是讓線程 B 得到執行然後獲取到 resource2 的監視器鎖。線程 A 和線程 B 休眠結束了都開始企圖請求獲取對方的資源,然後這兩個線程就會陷入互相等待的狀態,這也就產生了死鎖。

通過 jstack 命令分析(關鍵部分):

C:\jdk8_4\bin>jps -l
8016
2740 org.jetbrains.jps.cmdline.Launcher
9588 sun.tools.jps.Jps
10156 com.channel.kuaiqian.DeadLockDemo

C:\jdk8_4\bin>jstack 10156

輸出的部分內容如下:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x000000000338caf8 (object 0x000000076ba69c20, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000000000338a528 (object 0x000000076ba69c30, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.channel.kuaiqian.DeadLockDemo$2.run(DeadLockDemo.java:44)
        - waiting to lock <0x000000076ba69c20> (a java.lang.Object)
        - locked <0x000000076ba69c30> (a java.lang.Object)
"Thread-0":
        at com.channel.kuaiqian.DeadLockDemo$1.run(DeadLockDemo.java:26)
        - waiting to lock <0x000000076ba69c30> (a java.lang.Object)
        - locked <0x000000076ba69c20> (a java.lang.Object)

Found 1 deadlock.

在這裏插入圖片描述
可以看到 jstack 命令已經幫我們找到發生死鎖的線程的具體信息。

JDK 可視化分析工具

6、JConsole:Java 監視與管理控制檯
JConsole 是基於 JMX 的可視化監視、管理工具。可以很方便的監視本地及遠程服務器的 java 進程的內存使用情況。你可以在控制檯輸出console命令啓動或者在 JDK 目錄下的 bin 目錄找到jconsole.exe然後雙擊啓動。
連接 Jconsole
在這裏插入圖片描述
如果需要使用 JConsole 連接遠程進程,可以在遠程 Java 程序啓動時加上下面這些參數:

-Djava.rmi.server.hostname=外網訪問 ip 地址 
-Dcom.sun.management.jmxremote.port=60001   //監控的端口號
-Dcom.sun.management.jmxremote.authenticate=false   //關閉認證
-Dcom.sun.management.jmxremote.ssl=false

在使用 JConsole 連接時,遠程進程地址如下:

外網訪問 ip 地址:60001 

查看 Java 程序概況
在這裏插入圖片描述
內存監控
JConsole 可以顯示當前內存的詳細信息。不僅包括堆內存/非堆內存的整體信息,還可以細化到 eden 區、survivor 區等的使用情況,如下圖所示。

點擊右邊的“執行 GC(G)”按鈕可以強制應用程序執行一個 Full GC。
在這裏插入圖片描述
線程監控
類似我們前面講的 jstack 命令,不過這個是可視化的。

最下面有一個"檢測死鎖 (D)"按鈕,點擊這個按鈕可以自動爲你找到發生死鎖的線程以及它們的詳細信息 。
在這裏插入圖片描述
7、MAT
MAT 可以離線分享dump文件中, 堆棧信息。常用於找大對象、堆棧使用情況、內存溢出、內存泄漏等情況。
通用流程:jmap 導出堆棧信息、mat分析快照中的內存使用情況
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章