亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 JVM 入門教程 JVM 入門教程 JVM 參數:跟蹤類的加載與卸載

JVM 參數:跟蹤類的加載與卸載

1. 前言

本節內容主要是學習, JVM 跟蹤類的加載與卸載的常用參數配置,這是工作中跟蹤類的加載與卸載情況時 JVM 中最常用的參數配置。本節主要知識點如下:

  • 理解并掌握跟蹤類的加載與卸載的參數 -XX:+TraceClassLoading,為本節重點內容;
  • 理解并掌握跟蹤類的加載與卸載的參數 -XX:+TraceClassUnloading,為本節了解內容,非重點知識;
  • 理解并掌握跟蹤類的加載與卸載的參數 -XX:+PrintClassHistogram,為本節重點內容;

JVM 跟蹤類的加載與卸載的常用參數是使用 JVM 所必須的知識點,通篇皆為重點掌握內容,需要在理解的基礎上并掌握參數的使用方法。

2. 示例代碼準備

此處的示例代碼,與上一節的示例代碼相似,但是有重要的區別。詳細區別請看 Tips 的內容。

實例:準備測試代碼,創建一個 String 類型的 ArrayList,并在 list 中添加三個元素,分別是 “Hello”,“World”,“?。?!”。

Tips:注意,此處的示例代碼,并沒有執行 gc 操作。上一節的內容是為了跟蹤垃圾回收,所以需要手動調用 gc 方法而達到垃圾回收的效果。而此處我們討論的是類的加載與卸載,此處無需進行手動垃圾回收。

public class TracingClassParamsDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("Hello");
        list.add("World");
        list.add("!!!");
    }
}

3. -XX:+TraceClassLoading 參數

參數作用:-XX:+TraceClassLoading 參數是為了跟蹤類的加載。

為了更好的理解并掌握 -XX:+TraceClassLoading 參數,我們通過如下步驟進行操作。

  • 步驟 1:在 VM Options 中配置參數 -XX:+TraceClassLoading 并保存;
  • 步驟 2:運行示例代碼,觀察執行結果。

結果驗證:由于追蹤的結果日志非常龐大,此處僅展示具有代表性的類的加載。全部的類加載日志,請學習者自行執行代碼進行驗證。

[Opened C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.util.ArrayList$SubList from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.util.ListIterator from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.util.ArrayList$SubList$1 from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded DemoMain.TracingClassParamsDemo from file:/D:/GIT-Repositories/GitLab/Demo/out/production/Demo/]
[Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Shutdown from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]

結果分析:我們來對類的加載日志進行分析。

  • 第一行:Opened rt.jar。打開 rt.jar,rt.jar 全稱是 Runtime,該 jar 包含了所有支持 Java 運行的核心類庫,是類加載的第一步;
  • 第二行:加載 java.lang.Object。Object 是所有對象的父類,是首要加載的類;
  • 第三、四、五行:加載了 ArrayList 的相關類,我們的示例代碼中使用到了 ArrayList,因此需要對該類進行加載;
  • 第六行:加載我們的測試類 TracingClassParamsDemo ;
  • 第七行:加載 java.lang.Class 類,并加載類方法 MethodArray;
  • 第八行:加載 java.lang.Void 類,因為我們的 main 函數是 void 的返回值類型,所以需要加載此類;
  • 第九、十行:加載 java.lang.Shutdown 類, JVM 結束運行后,關閉 JVM 虛擬機。

從以上對日志的分析來看,JVM 對類的加載,不僅僅加載我們代碼中使用的類,還需要加載各種支持 Java 運行的核心類。類加載的日志量非常龐大,此處僅僅對重點類的加載進行日志的解讀,全部的類加載日志,請學習者自行執行代碼進行驗證。

4. -XX:+TraceClassUnloading 參數

參數作用:-XX:+TraceClassUnloading 參數是為了跟蹤類的卸載。由于系統類加載器加載的類不會被卸載,并且只加載一次,所以普通項目很難獲取到類卸載的日志。

此處我們先來看看,通過系統類加載器加載的類是否會被卸載。

為了更好的理解并掌握 -XX:+TraceClassUnloading 參數,我們通過如下步驟進行操作。

  • 步驟 1:在 VM Options 中配置參數 -XX:+TraceClassUnloading 并保存;
  • 步驟 2:運行示例代碼,觀察執行結果。

結果驗證:未打印日志,未發生類的卸載。

引出問題:為什么看不到跟蹤類卸載的日志呢?

上文提到了,由系統類加載器加載的類不能夠被卸載。所以想要看到跟蹤類卸載的日志,我們需要使用自定義的類加載器。通過自定義的類加載器加載的類,在類不可達的時候,會發生垃圾回收,并卸載該類。

一般情況下,開發過程中很少實現自定義的類加載器,除非有特殊的需求場景需要通過自定義的類加載器進行類的加載,因此此處對 -XX:+TraceClassUnloading 稍作了解即可。

5. -XX:+PrintClassHistogram 參數

參數作用:-XX:+PrintClassHistogram 參數是打印、查看系統中類的分布情況。

為了更好的理解并掌握 -XX:+PrintClassHistogram 參數,我們通過如下步驟進行操作。

  • 步驟 1:在 VM Options 中配置參數 -XX:+PrintClassHistogram 并保存;
  • 步驟 2:修改示例代碼,在代碼最后添加代碼 Thread.sleep(99999999999L),確保 main 函數長時間不能結束執行(當然了,也可以使用 while (true) 語句,進行無限長時間循環來創造這種場景,可自行選擇),以便于觀察類的分布情況;
public class TracingClassParamsDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("Hello");
        list.add("World");
        list.add("!!!");
        try {
            Thread.sleep(99999999999L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
  • 步驟 3:運行程序,觀察日志輸出;
  • 步驟 4:不中斷 main 函數的運行,將鼠標指針移動到日志輸出的 console 界面并單擊鼠標左鍵,確保鼠標的實時位置在 console 界面。按下鍵盤 Ctrl+Break 鍵,觀察日志輸出。

結果驗證:我們執行步驟 3 時,沒有觀察到日志的輸出。當我們嘗試步驟 4 時,獲取到了日志輸出如下圖所示。
圖片描述

結果分析: 這是系統中類的分布情況,那我們來看下日志中每列的表頭部分代表的意思:

  • num:自增的序列號,只是為了標注行數,沒有特殊的意義;
  • instances:實例數量,即類的數量;
  • bytes:實例所占子節數,即占據的內存空間大小;
  • class name:具體的實例。

我們取出第 3 條日志來進行下翻譯:系統當前狀態下,java.lang.String 類型的實例共有 2700 個,共占用空間大小為 64800 bytes。

6. 小結

圖片描述
本小節的重點內容即,我們所講述的三個常用的跟蹤類的加載與卸載參數,學習者需要對這三個常用參數的意義,以及使用方式進行掌握。

需要特別注意第二個參數 -XX:+TraceClassUnloading,在后續講解類加載器的時候,會實現自定義的類加載器,并使用該參數演示類的卸載。通篇皆為重點內容,需要認真對待,掌握本節要點內容。