深刻淺出Java類加載過程

學習筆記二之Java虛擬機中類加載的過程

當程序要使用某個類時,若是該類還未被加載到內存中,則系統會經過加載,鏈接,初始化三步來實現這個類進行初始化。java

1.    加載安全

加載,是指Java虛擬機查找字節流(查找.class文件),而且根據字節流建立java.lang.Class對象的過程。這個過程,將類的.class文件中的二進制數據讀入內存,放在運行時區域的方法區內。而後在堆中建立java.lang.Class對象,用來封裝類在方法區的數據結構。數據結構

類加載階段:學習

(1)Java虛擬機將.class文件讀入內存,併爲之建立一個Class對象。.net

(2)任何類被使用時系統都會爲其建立一個且僅有一個Class對象。指針

(3)這個Class對象描述了這個類建立出來的對象的全部信息,好比有哪些構造方法,都有哪些成員方法,都有哪些成員變量等。對象

Student類加載過程圖示:blog

 

2.    連接生命週期

連接包括驗證、準備以及解析三個階段。內存

(1)驗證階段。主要的目的是確保被加載的類(.class文件的字節流)知足Java虛擬機規範,不會形成安全錯誤。

(2)準備階段。負責爲類的靜態成員分配內存,並設置默認初始值。

(3)解析階段。將類的二進制數據中的符號引用替換爲直接引用。

說明:

符號引用。即一個字符串,可是這個字符串給出了一些可以惟一性識別一個方法,一個變量,一個類的相關信息。

直接引用。能夠理解爲一個內存地址,或者一個偏移量。好比類方法,類變量的直接引用是指向方法區的指針;而實例方法,實例變量的直接引用則是從實例的頭指針開始算起到這個實例變量位置的偏移量。

舉個例子來講,如今調用方法hello(),這個方法的地址是0xaabbccdd,那麼hello就是符號引用,0xaabbccdd就是直接引用。

在解析階段,虛擬機會把全部的類名,方法名,字段名這些符號引用替換爲具體的內存地址或偏移量,也就是直接引用。

3.    初始化

初始化,則是爲標記爲常量值的字段賦值的過程。換句話說,只對static修飾的變量或語句塊進行初始化。

若是初始化一個類的時候,其父類還沒有初始化,則優先初始化其父類。

若是同時包含多個靜態變量和靜態代碼塊,則按照自上而下的順序依次執行。

4.    小結

類加載過程只是一個類生命週期的一部分,在其前,有編譯的過程,只有對源代碼編譯以後,才能得到可以被虛擬機加載的字節碼文件;在其後還有具體的類使用過程,當使用完成以後,還會在方法區垃圾回收的過程當中進行卸載(垃圾回收)。

5.    附錄

常見問題:在本身的項目裏新建一個java.lang包,裏面新建了一個String類,能代替系統String嗎?

不能,由於根據類加載的雙親委派機制,會將請求轉發給父類加載器,父類加載器發現衝突了String就不會加載了。

6.    參考

【1】 周志明. 深刻理解Java虛擬機:JVM高級特性與最佳實踐(第二版)【M】.北京:機械工業出版社,2013  

【2】愛飛翔,周志明(譯).Java虛擬機規範(Java SE 8版)【M】.北京:機械工業出版社,2015.

【3】https://blog.csdn.net/ln152315/article/details/79223441

【4】https://blog.csdn.net/sinat_38259539/article/details/71794617

相關文章
相關標籤/搜索