本文將比較詳細介紹虛擬機類加載機制,主要知識來源於《深刻理解Java虛擬機》。java
任何一個Class文件都對應着惟一的一個類或者說接口的定義信息,在這個Class文件中,會保存相關信息。Class文件是一組以8 位字節爲基礎單位的二進制流,每個數據都有嚴格的定義,按照順序緊湊排列在Class文件中。安全
每個Class文件的頭4個字節稱之爲「魔數」,肯定這個文件是否爲一個能被虛擬機接受的文件。Class文件的魔數值爲:CAFEBABE,不一樣的文件有不一樣的魔數用於區分,感興趣的同窗能夠找相關的資料查閱一下,譬如:JPEG、text等的魔數是什麼。bash
Class文件包含:魔數、常量池、訪問標誌、(類索引、父索引、接口索引集合)、字段集合、方法表集合、屬性表集合。數據結構
類從被加載到虛擬機內存開始,到卸載出內存爲止,它的整個生命週期包括:加載、驗證、準備、解析、初始化、使用、卸載這七個階段。spa
加載是類加載過程當中的一個階段,在加載階段,虛擬機須要完成:線程
經過一個類的全限定名來獲取定義此類的二進制字節流;code
將字節流索表明的靜態存儲結構轉化爲運行時區的數據結構;對象
生成一個Class對象,做爲數據訪問的入口。繼承
驗證是鏈接階段的第一步,爲了確保Class文件的字節流中包含的信息符合當前虛擬機要求,不會危害虛擬機自身的安全。驗證須要進行四個階段的校驗動做:索引
文件格式驗證,便是否符合Class文件格式規範;
元數據驗證,便是否符合Java語言規範;
字節碼驗證,便是否符合虛擬機加載安全機制;
符號引用驗證,便是否符合類自己的信息。
準備階段是正式爲類變量分配內存並設置類變量初始值的階段,值得注意的是類變量不包括實例變量,而是基本數據變量,實例變量將在實例化時隨着對象一塊兒分配。
解析階段是虛擬機將常量池內的符號引用替換爲直接引用的過程,有四種引用解析過程:
類接口解析
字段解析
類方法解析
接口方法解析複製代碼
初始化階段是類加載過程當中最後一步,是執行類構造器方法的過程。跟以前步驟不同的是,本階段程序是主導和控制,而不是虛擬機主導和控制。
在類加載過程當中"經過一個類的全限定名來獲取定義此類的二進制字節流"這個動做放到Java虛擬機外部實現,讓程序決定如何獲取所須要的類,實現這個動做的代碼模塊稱爲」類加載器「。
在以前的文章中我說起到有關類與類加載器的知識有不清楚的地方,本文基本補充完畢,對於類的雙親委派機制,以及破壞雙親委派機制的相關知識再補充一些。
雙親委派機制對於保護Java程序的穩定運行很重要,但它的實現思想也很是簡單,實現代碼集中在ClassLoader類的loaderClass()方法中。邏輯:先檢查是否已經被加載過,如果沒有加載過則調用父加載器的loaderClass()方法,如果父加載器爲空則默認使用啓動類加載器做爲父加載器;若是父類加載器啓動失敗,拋出ClassNotFoundException異常,再調用本身的findClass()方法進行加載。
破壞雙親委派機制引入線程上下文類加載器,這個加載經過java.lang.Thread類的setContextClassLoaser()方法進行設置,若是建立線程時未設置,它會從父線程中繼承一個;若是在引用程序全局範圍內沒有設置,這個類的默認類加載是應用程序加載器。有關在哪些地方破壞雙親委派機制,以及爲何破壞能夠在前幾篇文章找。
本文要是有遺漏的地方,我將在評論區給出,同時若讀者發現本文不當之處也請在評論區指出,共同研究。