JVM-類載入(4)
阿新 • • 發佈:2022-05-25
類載入的三個階段
載入
將類的位元組碼載入到方法區中,內部採用 C++ 的 instanceKlass 描述java類
其重要的field有:
- _super 父類
- _fields 成員變數
- _methods 方法
- _constants 常量池
- _vtable 虛方法表
- _itable 介面方法表
- _class_loader 類載入器
- _java_mirror java的類映象
連結
連結階段又分為三個小階段:
驗證
驗證是否符合JVM規範,安全性檢查
準備
為static變數分配空間,設定預設值
- static變數在JDK7之前儲存與 instanceKlass 末尾,從JDK7開始,儲存於_java_mirror末尾
- static變數分配空間和賦值是兩個步驟,分配空間在準備階段,賦值在初始化階段完成
- 如果static變數是final的基本型別,那麼編譯階段值就確定了,賦值在準備階段完成
- 如果static變數是final的,但屬於引用型別,那麼賦值也會在初始化階段完成
解析
將常量池的符號引用解析為直接引用
初始化
初始化實際上是呼叫<cinit>()v,虛擬機器會保證這個類的構造方法的執行緒安全。
什麼時候會發生初始化
- main方法所在的類,總是會優先初始化
- 首次訪問這個類的靜態變數或靜態方法時
- 子類初始化會聯動父類的初始化
- 子類訪問父類的靜態變數,只會觸發父類初始化
- 執行Class.forName時
- new物件時
什麼時候不會發生初始化
- 訪問類的靜態常量時
- 類物件.class時
- 建立該類的陣列時
- 執行類載入器的loadClass方法時
- Class.forName的第二個引數(是否初始化)為false時