亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM分析之類加載機制是什么

發布時間:2022-08-10 10:56:10 來源:億速云 閱讀:221 作者:iii 欄目:開發技術

這篇文章主要講解了“JVM分析之類加載機制是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“JVM分析之類加載機制是什么”吧!

    1、前言

    JVM內部架構包含類加載器、內存區域、執行引擎等。日常開發中,我們編寫的java文件被編譯成class文件后,jvm會進行加載并運行使用類。本次僅對JVM加載部分進行分析,了解并掌握加載機制。

    2、類加載是什么

    類加載是一種過程,是將class文件加載到jvm內存的過程。當代碼邏輯中需要引用類時,通過類加載器加載引用類對象并存放堆中,以供代碼調用。

    3、類加載過程

    注:類加載過程包含 加載、鏈接(驗證、準備、解析)、初始化

    3.1 加載

    加載:將類的class字節碼文件讀到內存,將其存放到運行時數據區的方法區,然后在堆區生成class對象,封裝類在方法區內的數據結構。(方法區-》數據結構,堆區-》class對象)

    過程:java文件-》通過java c編譯成字節碼.class文件-》引導類加載器(裝載核心類庫)-》擴展類加載器(將指定目錄jar包裝載至工作庫)-》系統類加載器(將指定目錄的類和jar包裝載至工作庫,常用)-》自定義類加載器(實現加載指定類或自定義加密等操作)

    緩存:類加載到jvm后,會緩存一段時間(不管是否被引用),待jvm執行垃圾回收時才會回收未使用的緩存類,釋放空間。

    類加載器:

    • 啟動類加載器:Bootstrap ClassLoader由C/C++實現,嵌套在JVM中,java程序無法直接操作;負責加載Java核心類庫($JAVA_HOME中jre/lib目錄下或-Xbootclasspath參數指定的路徑目錄下,如java.*開頭的類)的class文件。

    • 擴展類加載器:Extension ClassLoader由Java編寫,由sun.misc.Launcher$ExtClassLoader實現。加載java平臺擴展的jar包,負責加載(java.ext.dirs目錄或$JAVA_HOMEjre/lib/ext目錄,如javax.開頭的類)的class文件。

    • 應用程序類加載器:Application ClassLoader由Java編寫,由sun.misc.Launcher$AppClassLoader實現。負責加載用戶類路徑(classpath)的class文件,java程序一般默認使用應用程序類加載器。

    • 自定義類加載器:一般情況下java程序使用上面三種類加載器就滿足了,一些特殊情況下,我們需要自定義加載指定路徑的類時,就需要繼承java.lang.ClassLoader類,重寫find Class或loadClass均可實現。(類隔離實踐中就采用此方案)

    類加載機制

    • 全盤負責:當加載器加載某個class時,該class所引用的其他class也一并被加載(自定義加載class除外);

    • 緩存機制:所有加載過的class均被緩存,當程序中使用某個class時,優先從緩存區中獲取,如果緩存區不存在,才會讀取該class的字節碼文件,加載為class對象,并存入緩存區,以便后續使用。(修改class后,需要重啟jvm才會生效)

    • 雙親委派:是一種類加載安全機制,當類加載器需要加載某個class文件時,會優先把加載委托給父類加載器處理,如果加載成功則返回,否則繼續向上委托直至最頂層類加載器,當父類加載器在加載范圍內均沒有找到所需class文件,即表示無法完成加載,此時子加載器才會去加載。(先向上委托父類加載器處理,都失敗后在自己再加載)

    • 反向委派:主要是用于第三方包加載,第三方包的類不在jdk/lib目錄,所以Bootstrap ClassLoader引導類加載器無法直接加載SPI(Service Provider Interface,服務提供者接口)的實現類,雙親委派機制中定義無法反向委托Application Classloader系統加載器加載,因此需要一種特殊的ContextClassLoader線程上下文類加載器來加載第三方的類庫。(*** 此處SPI接口后續文章分析 ***)

    加載實現方式

     /*
      * 類加載方式
      * 1、類加載器,此方式加載的class對象還沒有完成鏈接階段
      * 2、java.lang.Class,此方式加載的class對象是完成初始化的
      * */
     ClassLoader classLoader = ClassSegregationTest.class.getClassLoader();
     classLoader.loadClass("com.lgy.example.class_segregation.SegregationTestA");
     // 默認初始化class對象
     Class.forName("com.lgy.example.class_segregation.SegregationTestA");
     // 默認不初始化,并且指定類加載器進行加載
     Class.forName("com.lgy.example.class_segregation.SegregationTestA", false, classLoader);

    3.2 鏈接

    鏈接是將java二進制代碼合并至jvm運行的過程。

    鏈接過程可分為 驗證、準備、解析 三個階段。

    驗證

    保證正確加載類,包括文件格式驗證(Class文件格式的規范)、元數據驗證(Java語言規范)、字節碼驗證(通過數據流和控制流分析)、符號引用驗證。

    準備

    • 在方法區為靜態變量(static修飾)分配內存,并設置類變量初始值(通常是數據類型默認的零值,如0,0L,null,false等)。

    • 顯示賦值是在類對象實例化時處理(即 public static int x=10,準備階段初始值為0,在對象實例化時,才被賦值10)

    解析

    • 虛擬機中將常量池的符號引用(常量名)替換為直接引用(目標的指針地址)的過程;

    • 符號引用的目標不一定在內存中,但常量名(或稱字面量)是明確定義在jvm規范的class文件格式中。

    • 直接引用是指向目標的指針地址、相對偏移量或間接定位到目標的句柄,是肯定在內存中。

    3.3 初始化

    執行每個類的構造方法init()的過程,init()方法是java編譯器自動收集、合并所有類變量的賦值動作和靜態代碼塊語句,完成初始化。

    初始化步驟

    • 類未被加載或鏈接,則程序先加載并鏈接該類

    • 優先初始化直接父類,再執行子類初始化

    • 依次執行類中的初始化語句

    初始化條件(只有對類主動使用時才會初始化類)

    • 創建類實例(new Class)

    • 類或接口靜態變量的引用或賦值

    • 類靜態方法的調用

    • 反射加載(Class.forName(''))

    • 子類被初始化,其父類也會被初始化

    • jvm啟動時被標記啟動類的類,或直接java.exe命令運行指定類

    演示代碼如下:

     /**
     * 定義父類與子類
     */
     class Parent {
      public static int a = 10;
      static {
       System.out.println(" 父類初始化 ");
      }
     }
     class Children extends Parent{
      public static int a = 100;
      static {
       System.out.println(" 子類初始化 ");
      }
     }
     public static void main(String[] args) throws Exception {
      // 子類沒有定義變量a ( public static int a = 100;)
        System.out.println(Children.a); // 輸出 --  父類初始化 -- 10 
        // 主動調用時才會執行類的靜態塊
        -----------------------------------------
        // 子類定義變量a 
        System.out.println(Children.a); // 輸出 -- 父類初始化 -- 子類初始化  -- 100 
      // 子類被初始化時,優先初始化父類,所以父類靜態塊執行;調用變量a屬于子類定義,屬于主動調用,所以子類靜態塊執行
     }

    調試輸出加載對象(VM options 中添加 -XX:+TraceClassLoading

    • [Loaded com.lgy.example.class_segregation.Parent from file:/E:/dataway-demo/example/target/classes/]

    • [Loaded com.lgy.example.class_segregation.Children from file:/E:/dataway-demo/example/target/classes/]

    僅在首次主動使用才會被初始化。

    感謝各位的閱讀,以上就是“JVM分析之類加載機制是什么”的內容了,經過本文的學習后,相信大家對JVM分析之類加載機制是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    jvm
    AI

    盖州市| 承德县| 宝坻区| 博客| 新昌县| 融水| 黄石市| 军事| 穆棱市| 临沂市| 永靖县| 鄂尔多斯市| 平陆县| 锡林浩特市| 沅江市| 曲水县| 金塔县| 香格里拉县| 宽甸| 托里县| 广西| 榕江县| 桐柏县| 吉安县| 伊金霍洛旗| 盖州市| 龙陵县| 宝山区| 岳普湖县| 水富县| 夏津县| 东丰县| 贺州市| 晋城| 县级市| 阳西县| 宝坻区| 抚州市| 西充县| 沿河| 冀州市|