成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

手把手教你使用JConsole

開發 前端
我們通過線程 tab 看到了線程的 Runnable、WAITING 以及 BLOCKED 3 種狀態。要特別注意區分 WAITING 和 BLOCKED 狀態,簡單來說 WAITING 和我們的 wait 方法有關,而 BLOCKED 則和鎖有關。

目前市面上有多種 JVM 監控工具供我們選擇,其中 JConsole 可以算是 JVM 監控始祖了,從 JDK1.5 就開始引入。最關鍵的是 JConsole 是 JDK 官方自帶的控制臺,在一些特殊環境,比如網絡不通的情況下,可能是你唯一可以使用的圖形化監控工具了。因此我們有必要對 JConsole 的使用方法做一個了解。并且對大多數監控需求來說,JConsole 完全可以滿足我們的需要,今天我們就來看看一直被我們低估的 JConsole 到底如何使用。

首先我們先找到 JDK/bin 目錄下的 JConsole 命令,啟動 JConsole。下圖是我本機的 JConsole 啟動界面。

圖片圖片

我們可以看到,JConsole 啟動時在本地進程中會列出所有 JVM 進程 PID,相當于可視化的 jps 命令。我本機現在運行的幾個虛擬機進程分別是 StudyDemoApplication、JConsole、jps 和 idea。現在我們雙擊 StudyDemoApplication 進去看看。

進入具體的進程后,我們會看到幾個 tab 選項,其中概覽是我們需要重點關注的,概覽的內容比較直觀,包括了我們最關心的堆內存使用量、線程、類、CPU 使用情況這四個信息的曲線圖。除了概覽,被高頻使用的還有內存和線程 2 個 tab,下面我們分別介紹它們。

圖片圖片

內存

我們先來看內存 tab 吧。 內存這個 tab 用于監視虛擬機堆內存、非堆內存、內存池等的變化趨勢。可以通過圖表下拉框去選擇要監視的信息,還可以選擇時間范圍。

之前我在《 如何 使用 JVM 工具排查線上問題》課中介紹過 jstat 的使用方法,JConsole 內部集成了 jstat,圖形化的展示讓內存信息更直觀。注意,這里的下拉列表和你使用的垃圾收集器有關,比如默認使用的是 Parallel Scavenge 垃圾收集器,縮寫就是 PS,因此會看到 PS 前綴。

圖片

我們通過一個具體的例子來感受一下。下面這段代碼每隔 30 毫秒都會往 list 追加大小為 64KB 的 OOMObject 對象,此時我的堆設置是 100MB。

public class TestMemoryMonitor {
    /**
     * 存占位符對象,一個 OOMObject 大約占 64KB
     */
    staticclass OOMObject{
        publicbyte[] placeholder = newbyte[64 * 1024];
    }
    public static void fillHeap(int num) throws InterruptedException {
        List<OOMObject> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            //稍作延時,令監視曲線的變化更加明顯
            Thread.sleep(30);
            list.add(new OOMObject());
        }
        System.gc();
    }
    public static void main(String[] args) throws Exception {
        fillHeap(3000);
    }
 }

程序運行后,連接一下運行的 PID。在圖表列表中,選擇 內存池“PS Eden Space”,我們一起來看下內存的使用情況。

圖片圖片

我們看到 for 循環 1000 次執行完成后,形成了一個折線狀的圖。你可以看一下,右下角柱狀圖中的【堆】區域有 3 個柱狀圖,從左到右依次是“PS Old Gen”、“PS Eden Space”和“PS Survivor Space”。

我們可以看到在開始往堆填充數據時,出現了一條勻速向上的、趨近直線的折線。每隔 30 毫秒停止填充,曲線急劇下降,周而復始直至完成。我們再來看看圖表右下角的柱狀圖,當 for 循環執行結束,我們執行 System.gc() 后,Eden 和 Survivor 區中的空間幾乎都被釋放了,但是老年代的已使用空間還在緩慢增長。

顯然,我們的對象并沒有真正被釋放,而是在 System.gc() 發生之后進入了老年代。在我們的代碼中 List 在整個 fillHeap 方法中都是有效的,當我們執行 System.gc() 時并沒有離開 List 的作用域。

如果這個時候想要回收全部內存該怎么辦呢?你可以嘗試一下,把 System.gc() 放到 fillHeap 方法外運行一下試試,顯然由于此時 fillHeap 方法已經退出,List 不再有效,隨時可以被回收。

在實驗的時候要注意 System.gc() 并不一定總是有效的。這是因為 System.gc() 并不是強制執行的,而只是通知 JVM 快去回收對象,具體什么時候執行 JVM 說了算。這種感覺就像你在餐廳點菜,你覺得上菜比較慢,你就會催促服務員,但是催促服務員并不意味著立刻就會上菜,具體菜什么時候做好還是廚師說了算。

線程

接下來,我們聊聊另一個重要的 tab——線程。我在《 如何 使用 JVM 工具排查線上問題》課程中介紹過 jstack 命令,線程 tab 的功能基本和 jstack 命令一致。我們知道線程出現阻塞的原因包括: 等待外部資源、長時間執行的循環、鎖。

下面我們通過一段代碼來觀測常見的線程阻塞例子。

public static void createBusyThread(){
    Thread test1= new Thread(()->{while(true);});
    test1. start();
}
public static void createLockThread (final Object lock) {
    Thread test2= new Thread (()->{
    synchronized(lock){
                try{
                    lock. wait();
                }catch(InterruptedException e){
                }
            }});
    test2. start();
}
public static void main (String[] args) throws Exception {
    BufferedReader br= new BufferedReader( new InputStreamReader(System. in));
    br.readLine();
    createBusyThread();
    br.readLine();
    Object obj= new Object();
    createLockThread(obj);
}

監控線程的Runnable 狀態

我們在線程 tab 中可以看到 main 線程,你可以看一下圖片。右側堆棧顯示 readBytes 在參數輸入,此時線程還是 Runnable 狀態,Runnable 意味著線程會被分配 CPU 時間片,readBytes 發現沒有任何輸入又會歸還 CPU 時間片,這種性能消耗幾乎可以忽略不計。

圖片圖片

接著監控 test1 線程,test1 線程執行的是自旋操作,從右側的堆棧中我們可以發現線程此時在 MonitoringTest.java 代碼的 41 行,而第 41 行就是死循環。顯然這種自旋會極大浪費 CPU 資源。

圖片圖片

監控線程的 WAITING 狀態

下面我們再來看看 test2 線程,圖片顯示 test2 線程在等待某個鎖,線程這時候處于 WAITING 狀態。test2 線程處于一個正常的狀態,它在等待一個鎖,直到鎖對象被 notify 調用才會繼續執行。

圖片圖片

監控線程的 BLOCKED 狀態(死鎖)

下面我們看一個死鎖的例子。出現線程死鎖之后,我們可以看到一個新的“死鎖”tab。

圖片圖片

圖中我們可以很清晰地看到 43 號線程在等待一個 Integer 對象,這個對象被 12 號線程持有。而點擊 12 號線程則顯示它也在等待一個 Integer 對象,這個對象被 43 號線程持有,43 號線程和 12 號線程形成了死鎖,是不是很直觀?

總結

以上就是我們講的 JConsole 的常用用法,可以看到,我們日常的監控、死鎖判斷、內存排查都可以使用 JConsole 去排查。在沒有圖形化的生產環境可以使用 JConsole 遠程連接。對 JConsole 的使用大多數是線上問題診斷。既然要診斷,最重要的還是基于我們的研發經驗,JConsole 只是工具而已,不能本末倒置,認為有一個工具就可以解決問題了,更需要的是我們人為的判斷。

此外,我們通過線程 tab 看到了線程的 Runnable、WAITING 以及 BLOCKED 3 種狀態。要特別注意區分 WAITING 和 BLOCKED 狀態,簡單來說 WAITING 和我們的 wait 方法有關,而 BLOCKED 則和鎖有關。

責任編輯:武曉燕 來源: 程序員技術充電站
相關推薦

2021-07-14 09:00:00

JavaFX開發應用

2022-12-07 08:42:35

2011-01-10 14:41:26

2011-05-03 15:59:00

黑盒打印機

2021-08-02 07:35:19

Nacos配置中心namespace

2022-07-22 12:45:39

GNU

2022-10-30 10:31:42

i2ccpuftrace

2020-05-15 08:07:33

JWT登錄單點

2021-03-12 10:01:24

JavaScript 前端表單驗證

2021-12-15 08:49:21

gpio 子系統pinctrl 子系統API

2011-02-22 13:46:27

微軟SQL.NET

2021-02-26 11:54:38

MyBatis 插件接口

2021-12-28 08:38:26

Linux 中斷喚醒系統Linux 系統

2021-01-19 09:06:21

MysqlDjango數據庫

2023-04-26 12:46:43

DockerSpringKubernetes

2022-01-08 20:04:20

攔截系統調用

2022-03-14 14:47:21

HarmonyOS操作系統鴻蒙

2022-07-27 08:16:22

搜索引擎Lucene

2020-12-08 10:32:15

Python郵件tcp

2022-04-12 08:46:12

i2c-tools開源工具
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产ts人妖另类 | 国产一区二区三区精品久久久 | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 人人干视频在线 | 久国产 | 国产精品第2页 | 久久99精品久久久久久 | 日本一区二区视频 | 日本精品免费 | 久久99精品久久久久久琪琪 | 天天天天操 | 欧美亚洲国产一区二区三区 | 天天插天天操 | 99热精品久久 | 欧美亚洲国产精品 | 国产剧情久久 | 性一爱一乱一交一视频 | 精品亚洲一区二区 | 国产精品成人国产乱一区 | 九九精品久久久 | 九色在线 | 国产高潮好爽受不了了夜夜做 | 欧美高清dvd | 日韩在线视频观看 | 国产99久久久国产精品 | 国产午夜精品一区二区三区嫩草 | 亚洲三区视频 | 日本精品免费在线观看 | 一级毛片免费 | 求个av网址 | 国产99久久精品一区二区永久免费 | 国产精品久久亚洲 | 视频一区二区在线观看 | 成人在线一区二区三区 | 久久久久精 | 久久毛片| 欧美成人一区二区三区 | 91看片视频| 国产原创在线观看 | 国产欧美一区二区三区在线看 | 午夜免费视频 |