一文淺析Java中類加載過程

學習總結於:《深入瞭解JAVA虛擬機》-周志明
類加載相關文章索引:
一文弄懂Java中類加載器的關係
Java中雙親委派機制的實現原理
Java中自定義類加載器

Java 類的聲明週期

類從被加載到虛擬機內存中開始,直到卸載出內存,整個生命週期分爲以下七個階段:

在這裏插入圖片描述
類加載過程就是指:加載、驗證、準備、解析和初始化這五個階段

Java 類加載過程

加載

在加載階段,虛擬機會做以下三件事情:

  1. 通過一個類的全限定名來獲取定義此類的二進制流。
  2. 將這個二進制流所代表的的靜態儲存結構轉化成方法區的運行時數據結構。
  3. 在內存中生成這個類的java.lang.class對象(不一定是在堆內存中,HotSpot認爲這個Class對象比較特殊,將它放在方法區裏面)。

驗證

驗證階段的目的是爲了確保Class文件的字節流包含的信息,符合JVM的要求,並且不會危害JVM的安全。

準備

準備階段是正式爲類變量 (使用 static 修飾的,又叫 “靜態變量”) 進行內存分配和設置初始值的階段,這些變量使用的內存都在方法區中進行分配。
注意: 這裏有一個容易混淆的地方,這時候進行分配的僅僅僅僅僅包括靜態變量,就是被 static 修飾的,不會分配實例變量的內存,而實例變量的內存將會隨着對象實例化的時候分配在堆內存中。而且這裏的初始化通常都是數據類型的零值,比如:

public static int a = 123;

變量 a 在這個階段的初始值是 0,而不是123!!切記!!

如果是引用數據類型的零值就是 null,如果是 boolean 的零值就是false。
把變量 a 初始化爲 123 會在後面 “初始化” 階段進行。

上面說到通常是零值,那麼也有特殊情況。比如:

public static final int a = 123;

如果使用 final修飾,那麼在這個準備階段就會初始化爲123。

解析

解析階段比較複雜,簡單來說就是虛擬機將常量池中符號引用轉換成直接引用的過程。

初始化

初始化階段是類加載階段的最後一步。到了這一階段,虛擬機才真正的執行Java程序代碼。這一階段就是虛擬機執行類構造器 clinit() 方法的過程,此方法是編譯器收集類中所有類變量(靜態變量)和靜態代碼塊中的語句,然後進行合併產生的。


技 術 無 他, 唯 有 熟 爾。
知 其 然, 也 知 其 所 以 然。
踏 實 一 些, 不 要 着 急, 你 想 要 的 歲 月 都 會 給 你。


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