深入Java虛擬機之 – 類加載機制
一、類加載機制
虛擬機把描述類的數據從Class文件 (二進制流) 加載到內存,並對數據結構進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是Java的類加載機制。如下圖:
二、類加載的時機
類從加載到虛擬機的內存開始,到卸載出內存結束,中間會經歷7個階段,即加載、驗證、準備、解析、初始化、使用和卸載;其中 驗證、準備和解析也被稱爲連接。
其中,加載、驗證、準備、初始化和卸載這五個順序是固定的,而解析則不一定,因爲Java是動態語言,它支持動態綁定,或在初始化後開始;現在對這些狀態進行解釋分析
2.1 加載
加載過程主要完成以下3件事
-
- 通過一個類的全限名來獲取定義此類的二進制字節流
-
- 將這個字節流所代表的靜態存儲結構轉換爲方法區的運行時數據結構
-
- 在內存中生成一個代表這個類的 java.lang.Class對象,作爲方法區這個類的各種數據和訪問入口
而獲取二進制字節流的方式可以有很多種,不一定是通過類的全限名;比如從 ZIP 讀取,網絡中讀取或者動態代理讀取等等。
加載階段和連接階段的部分內容,是交叉進行的。
- 在內存中生成一個代表這個類的 java.lang.Class對象,作爲方法區這個類的各種數據和訪問入口
2.2 驗證
這一階段是爲了確保 Class 文件中的字節流是否符合當前虛擬機的要求,並且不會傷害到虛擬機自身安全。
2.3 準備
準備階段正式爲類變量分配內存和設置初始值的階段,這些變量所使用的內存將在方法區中進行分配。
2.4 解析
解析是把符號引用轉換爲直接引用的過程;在 class 文件格式中,符號引用常常以,CONSTANT_FIELDREF_INFO等等類型的常量出現。
2.5 初始化
初始化是類加載的最後一步,也是真正執行類中定義的 Java 程序代碼,初始化階段是執行類構造器 ()方法的過程。
三、類加載器
從上面看到,類加載階段中,是通過一個 類的全限定名來獲取描述此類的二進制字節流 的,這個動作如果放到外部去做,以便程序自己決定如何去獲取所需要的類。我們叫做 “類加載器”。
四、雙親委派模型
它的工程流程是: 當一個類加載器收到類加載的請求,它首先不會自己去嘗試加載這個類,而是委派給她的父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載器都會傳遞到父加載器中;只有父加載器無法完成時,子加載器纔會嘗試自己去加載.