JVM-類載入機制,jvm-載入機制
虛擬機器類載入機制
虛擬機器把描述的類的資料從class檔案載入到記憶體後,並對資料進行校正,轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java類型,這就是虛擬機器的類載入機制。
類載入的時機
類被載入到虛擬機器記憶體開始,到卸載出記憶體為止。它的整個生命週期包括:類載入(Loading),驗證(Verification),準備(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸載(Unloading)7個階段。其中驗證,準備,解析3個部分統稱為串連(Linking)。
虛擬機器規範嚴格規定了有且僅有5種情況必須立即對類進行“初始化”:
類載入的過程
一、載入
(1)在載入階段,虛擬機器需要完成以下3件事:
(2)數組類本身不通過類載入器建立,他是由Java虛擬機器直接建立的。
一個數組類建立過程遵循以下規則:
二、驗證
驗證是串連階段的第一步,這一階段的目的是為了確保class檔案的位元組流包含的資訊符合當前虛擬機器的要求,並且不會危害虛擬機器本省的安全。
驗證階段大致上會完成以下4個階段的檢驗動作:檔案格式驗證、中繼資料驗證、位元組碼驗證、符號引用驗證
(1 ) 檔案格式驗證
(2 ) 中繼資料驗證
(3 ) 位元組碼驗證
(4 ) 符號引用驗證
三、準備
準備階段是正式為類變數 分配記憶體並設定類變數初始值的階段,這些變數所使用的記憶體將在方法區中進行分配。
四、解析
(1)解析階段是虛擬機器將常量池內的符號引用替換為直接引用的過程。
(2)虛擬機器規範中並未規定解析階段發生的具體時間,只要求了執行anewarray,checkcast,getfield,getstatic,instanceof,invokedynamic,invokeinterface,invokespecial,invokestatic,invokevirtual,ldc,ldc_w,multianewarray,new,putField和putstatic這16個用於操作符號引用的位元組碼指令之前,先過它們所使用的符號引用進行解析。
(3)解析動作主要針對類或介面,欄位,類方法,介面方法,方法類型,方法控制代碼和調用點限定符7類符號引用進行。
(4)類或介面的解析
虛擬機器完成整個解析的過程需要以下3個步驟
1)如果c不是一個數群組類型,那虛擬機器將會把代表N的全限定名傳遞給D的類載入器去載入這個類C。在載入過程中,由於中繼資料驗證,位元組碼驗證的需要,又可能觸發其他相關的類的載入動作。
2)如果C是一個數群組類型,並且數組的元素類型為對象,那將會按以上的規則載入數群組類型。如果N的描述符如前面所假設的形式,需要載入元素的類型,接著由虛擬機器產生一個代表此數組維度和元素的數組對象。
3)如果上面的步驟沒有出現任何異常,那麼C在虛擬機器中實際上已經成為一個有效類或介面了,但在解析完成之後還要進行符號引用驗證,確認D是否是具備對C的存取權限。
(5)欄位解析
(6)類方法解析
(7)介面方法解析
五、初始化
類載入器
一、類與類載入器
對於任意一個類,需要由載入它的載入器和這個類本身一同確立其在Java虛擬機器中的唯一性,每一個類載入器,都擁有一個獨立的類名稱空間。
二、雙親委派模型
(1)從Java虛擬機器的角度來講,只存在兩種不同的類載入器:一種是啟動類載入器(Bootstrap Class ClassLoader),這個類載入器使用C++語言實現是Java虛擬機器自動的一部分;另一種就是所有其他的類載入器,這些類載入器都由Java語言實現,獨立於虛擬機器外部,並且全都是繼承自抽象類別java.lang.classLoader.
(2)細分:啟動類載入器(Bootstrap ClassLoader)
擴充類載入器(Extension ClassLoadert)
應用程式類載入器(Application ClassLoader)[系統類別載入器]
(3)雙親委派模型工作過程:
如果一個類載入器收到了類載入器的請求,它首先不會自己去嘗試載入這個類,而是把這個請求委派給父類載入器去完成,每一個層次的類載入器都是如此,因此所有的載入請求最終都應該傳送到頂層類載入器中只有當父類載入器反饋自己無法完成這個類載入請求時,子類載入器才會嘗試自己去載入。