虛擬機類加載機制

本篇文章講述虛擬機如何加載Class文件和Class文件中的信息進入到虛擬機後會發生什麼變化java

1.類加載的時機數據結構

類被加載到虛擬機的內存中,他的整個生命週期包含了:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)七個階段,其中驗證、準備和解析三個部分稱爲連接(Linking)。spa


對於什麼階段開始類加載的第一個階段:加載,在虛擬機的規範中沒有約束,可是對於初始化階段,虛擬機則嚴格對四種狀況進行了要求必須對類進行初始化對象

1.遇到new、getstatic、putstatic或者invokestatic這四條字節碼指令的時候(場景:即便用new關鍵字實例化對象的時候,讀取或者設置一個類的靜態字段的時候,以及調用一個靜態的方法的時候)接口

2.使用java.lang.reflect包的方法對類進行反射調用的時候,若是類沒有進行過初始化,則須要觸發其初始化生命週期

3.當初始化一個類的時候,若是一個類的父類尚未進行初始化,則要先觸發父類的初始化。內存

4.當虛擬機啓動的時候,虛擬機會先初始化包含main方法的那個主類字符串


好比:在A類中引用B類中的靜態字符串常量b,在編譯的時候,對常量B.b的引用實際都被轉化爲A類對自身的常量池的引用了,兩個類在編譯成Class以後就不存在任何聯繫了。get

接口的加載:編譯器會爲接口生成「<clinit>()」類構造器,用於初始化接口的成員變量,接口和類的真正區別是上面的3,在一個接口初始化的時候,並不會要求其父接口所有都初始化,只有真正用到父接口的時候(如引用接口中定義的常量)纔會初始化。編譯器


類加載的過程

就上面的加載~初始化五個階段

1.加載階段 :1)經過類的全限定名獲取定義此類的二進制字節流  2)將這個字節流的靜態存儲結構轉化爲方法區的運行時數據結構 3)在堆中生成java.lang.Class對象,做爲方法區的訪問入口

2.驗證階段:主要是確保Class文件的字節流包含的信息符合要求虛擬機的要求,不會危害計算機(具體過程很複雜)

3.準備階段:正式爲類變量分配內存並設置類變量的初始值的階段,這些內存都在方法區分配,須要強調的是,這裏分配的內存僅包括類變量,不包括實例變量,實例變量將會在對象的實例化時一塊兒分配到Java堆中,這裏說的初始值指的是類變量的零值,例如 public static int a = 56,在準備階段時,a=0.其賦值是在類的構造器的<clinit>()的方法之中,賦值階段將會在初始化階段纔會被執行。若是是public static final int a = 56 在準備階段就是a = 56了。

相關文章
相關標籤/搜索