Java:JVM的類加載過程,你真的懂?

1. 問:什麼是類加載機制?
答:JVM虛擬機把描述類的數據從Class文件(.class)加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。
2. 問:類加載的過程是什麼?
答:類從加載如內存,到使用,到使用完畢卸載出內存爲止的 生命週期爲七個階段:發生順序
3. 問:什麼時候需要加載類?
答:當你需要使用這個類的時候。比如 ①遇到new,getstatic,putstatic指令時,②使用java.lang.reflect包中的方法對類進行反射調用時,③初始化某個類的子類時,④main方法所在類,⑤JDK1.7動態語言支持時

4. 問:什麼時候不會初始化一個類(不初始化不代表不需要)?
答:①通過類名獲取Class對象(類名.class),
②class.forName加載指定類:Class.forName(String name, boolean initialize,ClassLoader loader)且指定參數initialize爲false時,只加載,連接不初始化
③classLoader默認的loadClass方法:ClassLoader.loadClass(className),只加載,連接,不初始化,
④定義數組和集合
⑤static final常量時

一:加載(Load)

loadClass()方法獲得字節流
JVM做的事:
①通過類的全限定名獲取此類的二進制字節流 – 此動作的代碼模塊稱爲“類加載器”
②字節流的靜態存儲結構轉化爲方法區的運行時的數據結構
③內存中聲稱該類的java.lang.Class 對象, 作爲該類在方法中的訪問接口

二:連接(Linking)

2.1 驗證(Verification)

確保class文件的字節流符合當前JVM的要求
驗證過程:
①文件格式驗證:模數是否爲0xCAFEBABE
②元數據驗證: 字節碼語義分析,是否合乎Java語言規範
③字節碼驗證:數據流和控制流分析,類的方法體校驗分析
④符號引用驗證:解析動作能否正確執行

2.2 準備(Preparation)

爲類的靜態變量分配內存,並賦予默認值:
含 static 賦爲 (0,0L,nulll,false)
含 static final(靜態字面值常量)直接賦等號後面的值爲初始值

2.3 解析(Resolution)

JVM中 符號引用 替換爲 直接引用(內存地址)
直接引用: 直接引用可以是直接指向目標對象的指針、相對偏移量或是一個能間接定位到目標的句柄。直接引用是與虛擬機內存佈局實現相關的,同一個符號引用在不同虛擬機實例上翻譯出來的直接引用一般不會相同,如果有了直接引用,那引用的目標必定已經在內存中存在。
針對 下四類符號引號 對應的常量池內四類常量類型

符號引用 常量池內常量類型
類或接口 Constant_Class_Info
字段 Constant_Fieldref_Info
類方法 Constant_Methodef_Info
接口方法 Constant_InterfaceMethoder_Info

三:初始化(Initialization)

執行 類構造器 <clinit>()方法,什麼時候需要初始化(見問題3) 。clinit方法:按照語句在源文件中出現的順序,編譯器自動收集所有類變量的賦值動作(靜態變量)和靜態語句塊(static塊)中的語句併合並。
在編譯生成class文件時,編譯器會產生兩個方法加於class文件中,一個是類的初始化方法clinit, 另一個是實例的初始化方法init。區別類構造器 <clinit>()實例的初始化方法 或稱 類的構造函數 <init>()
類構造器只執行一次,且必須先執行父類的clinit方法,(最終追溯到java.lang.Object爲第一個執行)。
clinit方法:按照語句在源文件中出現的順序,編譯器自動收集所有類變量的賦值動作(靜態變量)和靜態語句塊(static塊)中的語句併合並。
如果類中沒有靜態變量或靜態代碼塊(接口中沒有靜態代碼塊),那麼clinit方法將不會被生成。
類的構造函數:實例化一次執行一次,且必須先執行父類的init方法。
init方法:根據源碼中的順序執行賦初值或代碼塊,先爲實例變量分配內存空間,再執行賦默認值。
如果類中沒有成員變量和代碼塊,沒有init方法。

雙親委派模型(Parent Delegation Model):

JVM的兩種類加載器:
兩種類加載器
對於用戶來說:JVM的類加載器:
雙親委派模型
某一類加載器收到類加載請求,會先將請求委派給父類加載器完成(最終均發送到啓動類Bootstrap ClassLoader),若父反饋沒有找到對於的類(請求失敗),纔會嘗試子加載器。不同的classLoader加載的類是相隔離得。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章