【Java虚拟机规范】JVM类加载机制
【Java虛擬機規范】JVM類加載機制
理論知識
一個類型從被加載到虛擬機內存中開始,到卸載出內存為止,它的整個生命周期將會經歷加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)七個階段,其中驗證、準備、解析三個部分統稱為連接(Linking)。
《Java虛擬機規范》嚴格規定了有且只有六種情況必須立即對類進行“初始化”(而加載、驗證、準備自然需要在此之前開始)。
遇到new、getstatic、putstatic或invokestatic這四條字節碼指令時,如果類型沒有進行過初始化,則需要先觸發其初始化
使用new關鍵字實例化對象的時候。
讀取或設置一個類型的靜態字段(被final修飾、已在編譯期把結果放入常量池的靜態字段除外)。
調用一個類型的靜態方法的時候。
使用java.lang.reflect包的方法對類型進行反射調用的時候,如果類型沒有進行過初始化,則需要先觸發其初始化。
當初始化類的時候,如果發現其父類還沒有進行過初始化,則需要先觸發其父類的初始化。
當虛擬機啟動時,用戶需要指定一個要執行的主類(包含main()方法的那個類),虛擬機會先初始化這個主類。
當使用JDK 7新加入的動態語言支持時,如果一個java.lang.invoke.MethodHandle實例最后的解析結果為REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四種類型的方法句柄,并且這個方法句柄對應的類沒有進行過初始化,則需要先觸發其初始化。
當一個接口中定義了JDK 8新加入的默認方法(被default關鍵字修飾的接口方法)時,如果有這個接口的實現類發生了初始化,那該接口要在其之前被初始化。
加載(Loading)
通過一個類的全限定名來獲取定義此類的二進制字節流。
將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構。
在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入
口。
驗證
文件格式驗證,驗證字節流是否符合Class文件格式的規范,并且能被當前版本的虛擬機處理。
元數據驗證,對字節碼描述的信息進行語義分析,以保證其描述的信息符合《Java語言規范》的要
求。
字節碼驗證,驗證程序語義是合法的、符合邏輯的。
符號引用驗證,驗證是否缺少或者被禁止訪問它依賴的某些外部類、方法、字段等資源,發生在將符號引用轉換為直接引用得過程–解析階段中發生。
準備
為類變量分配內存并設置類變量初始值的階段。
解析
Java虛擬機將常量池內的符號引用替換為直接引用的過程。
初始化
進行準備階段時,變量已經賦過一次系統要求的初始零值,而在初始化階段,則會根據程序員通
過程序編碼制定的主觀計劃去初始化類變量和其他資源。
實例講解
JVM在什么時候會去加載我們得類呢?從實用得角度出發,就是在代碼中用到這個類得時候。舉個例子,比如下面你有一個類(UserService.class),里面有一個“main()”方法作為主入口。那么一旦你的JVM進程啟動之后,它一定會先把你的這個類(UserService.cass)加載到內存里,然后從“main()”方法的入口代碼開始執行。
接著我們加上如下代碼
public class UserService {public static void main(String[] args) {CarManager carManager = new CarManager();} }大家可以看到程序需要使用到CarManager,此時就會觸發JVM加載CarManager到內存里來使用。
驗證
簡單來說,這一步就是根據Java虛擬機規范,來校驗你加載進來的“.class”文件中的內容,是否符合指定的規范。以免class文件損壞或者被修改后不符合規范導致得JVM執行不了這個字節碼。
準備
準備階段會為類分配內存空間,給類變量分配空間并賦一個初始值。
在準備階段中會給age變量賦初始值0。
解析
將符號引用替換為直接引用
初始化
我們先看下如下代碼,我們在什么時候通過
答案就是初始化階段我們會進行Configuration.getConfiguration(“sys.user.age”)值獲取并且賦值給age這個類變量。
以上就是本期內容,期待小伙伴們一起學習類加載機制,在評論區溝通交流。
參考《深入理解java虛擬機》
Remi醬記得關注一下哦~~
總結
以上是生活随笔為你收集整理的【Java虚拟机规范】JVM类加载机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ElasticSearch集成Sprin
- 下一篇: 这几种Java异常处理方法,你会吗?