1. 程式人生 > >【Java】「深入理解Java虛擬機」學習筆記(5)- 類加載

【Java】「深入理解Java虛擬機」學習筆記(5)- 類加載

一次 some img 不同的 各路 轉換 準備 自己 綁定

  C/C++在編譯時需要進行連接,而Java的類加載、連接和初始化是在運行時完成的。 

技術分享圖片

     圖 類的生命周期

  圖中解析的過程不一定在準備和初始化之間,也可以在初始化之後再開始,以支持Java的運行時動態綁定。

一、類加載過程

  1、加載

    加載是整個“類加載”過程的第一個階段。這一步也叫“加載”,可以理解為把類從文件中讀取到內存中並按一定數據結構保存以備後續使用。

    主要分為三個步驟:

      ①通過類的全限定名獲取其字節碼。

      ②將字節碼中的靜態存儲結構轉換成方法區的運行時數據結構。

      ③在內存中創建一個代表這個類的java.lang.Class對象,作為該類的元數據訪問入口。那麽你現在知道了反射的時候,someClass.class這個對象是怎麽來的了吧?只要拿到這個class你想創建實例、調用方法都行,想幹哈就幹哈。

    數組的加載有所不同,因為數組本身是VM自己創建的,但數組中的元素類型可能是類,還是要靠類加載器去加載。所以數組的加載分兩種情況:

      ①當數組的類型是引用類型,那就遞歸按照上面的方法加載。

      ②當數組的類型是基本數據類型如int [],則VM將會將該數組標記為與Bootstrap加載器關聯。

  2、驗證

    驗證的目的是確保當前字節碼文件中的內容,符合當前VM的要求,不會給VM運行造成危害。

    驗證過程包括:文件格式驗證、元數據驗證、字節碼驗證和符號引用驗證。 

    這一步作用類似於語法檢查。因為字節碼的編譯是在JVM之外進行的(可能來自本地jar包甚至網絡),不同版本的編譯器生成不同版本規範的字節碼,可能帶來兼容性問題。另外,也能防範惡意的字節碼修改影響虛擬機的運行穩定。   

  3、準備

    這個過程主要是為類變量分配內存(分配在方法區中)並賦默認初值(如int的初值為0,char為‘\u0000‘)。

  4、解析

    解析是將常量池內的符號引用替換為直接引用的過程。

  5、初始化

    初始化就是執行構造方法的過程。

♣所以你應該知道了成員變量初始化時刻有兩次

  一次是在類加載的準備過程中、然後就是在調用構造方法的時候。

二、類加載器

  類加載器有各自的類名稱空間,兩個類加載器即使加載了同一個.class文件,生成的類被認為是不同的類。這也可以理解,它們在方法區本來保存的就是兩份。

  1、類加載器分類

  技術分享圖片

  2、雙親委派模型

    雙親委派的流程就是甩鍋的過程。Bootstrap是頂層Loader,UserDef是底層Loader。底層Loader在接到類加載指令時啥也不幹,把鍋直接甩給上一層Loader,依次類推

  直到鍋甩到Bootstrap(也就是說所有的鍋都會到它這兒)。如果Bootstrap的路徑裏有這個類,算它倒黴它加載,否則它再把鍋彈回給下一層Loader—Extension,如果

  Extension的類路徑裏有這個類,它加載。依次類推。。。

    雙親委派模型的好處是:它的這種上層優先的層級關系保證了,類加載的有序性,不會因為各路Loader自行加載導致的混亂。

    

【Java】「深入理解Java虛擬機」學習筆記(5)- 類加載