天天看點

JVM監控及診斷工具之JConsole

學習 尚矽谷 宋紅康 JVM從入門到精通 的學習筆記

概述

從jdk5開始,在jdk中自帶的Java監控和管理控制台.

用于對jvm中的記憶體(記憶體分的展示的也比較細緻)、線程(線程有多少個)和類(加載了多少個類)等監控,

建議直接跳過JConsole,直接學習Visual VM ,畢竟這兩個都是jdk自帶的。

使用

啟動方式

兩種啟動方式:

1.在jdk安裝目錄中找到jconsole.exe,輕按兩下該可執行檔案就可以

2. 打開cmd 的 DOS視窗,直接輸入jconsole就可以了      

連接配接方式

Local

使用JConsole連接配接一個正在本地系統運作的JVM,并且執行程式的和運作JConsole的需要是同一個使用者。JConsole使用檔案系統的授權通過RMI連接配接起連結到平台的MBean的伺服器上。這種從本地連接配接的監控能力隻有Sun的JDK具有。      

注意:本地連接配接要求 啟動jconsole的使用者 和 運作目前程式的使用者 是同一個使用者

具體操作如下:

1、在DOS視窗中輸入jconsole

JVM監控及診斷工具之JConsole

2、在控制台上填寫相關資訊

JVM監控及診斷工具之JConsole

3、選擇“不安全的連接配接”

JVM監控及診斷工具之JConsole

4、進入控制台頁面

JVM監控及診斷工具之JConsole

Remote

使用下面的URL通過RMI連接配接器連接配接到一個JMX代理,service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi。JConsole為建立連接配接,需要在環境變量中設定mx.remote.credentials來指定使用者名和密碼,進而進行授權。      

Advanced

使用一個特殊的URL連接配接JMX代理。一般情況使用自己定制的連接配接器而不是RMI提供的連接配接器來連接配接JMX代理,或者是一個使用JDK1.4的實作了JMX和JMX Rmote的應用      

功能示範基本示範

import java.util.ArrayList;
import java.util.Random;

/**
 * -Xms600m -Xmx600m -XX:SurvivorRatio=8
 * @author shkstart  [email protected]
 * @create 2020  17:51
 */
public class HeapInstanceTest {
    byte[] buffer = new byte[new Random().nextInt(1024 * 100)];

    public static void main(String[] args) {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ArrayList<HeapInstanceTest> list = new ArrayList<HeapInstanceTest>();
        while (true) {
            list.add(new HeapInstanceTest());
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}      

啟動上面的代碼

JVM監控及診斷工具之JConsole

選擇你啟動的Java程序

選擇“不安全的連接配接”

JVM監控及診斷工具之JConsole
JVM監控及診斷工具之JConsole

記憶體區域

JVM監控及診斷工具之JConsole

程式在執行的過程中跑的線程有哪些

JVM監控及診斷工具之JConsole

加載的類的個數

JVM監控及診斷工具之JConsole

虛拟機的概述資訊

JVM監控及診斷工具之JConsole

示範檢測死鎖

public class ThreadDeadLock {

    public static void main(String[] args) {

        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        new Thread(){
            @Override
            public void run() {

                synchronized (s1){

                    s1.append("a");
                    s2.append("1");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (s2){
                        s1.append("b");
                        s2.append("2");

                        System.out.println(s1);
                        System.out.println(s2);
                    }

                }

            }
        }.start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (s2){

                    s1.append("c");
                    s2.append("3");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (s1){
                        s1.append("d");
                        s2.append("4");

                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
            }
        }).start();

    }
}