JVM(三)JVM的ClassLoader類加載器
1、類加載的生命周期
類從被加載到虛擬機內存中開始,到卸載出內存為止,它的整個生命周期包括:
(1)加載
(2)驗證
(3)準備
(4)解析
(5)初始化
(6)使用
(7)卸載
一共7個階段。其中驗證、準備、解析這3個階段統稱為連接。
這類加載的7個階段順序流程:
加載、驗證、準備、初始化和卸載這5個階段的順序是確定的。類的加載過程中必須按照這種順序按部就班地開始,而解析階段則是不一定的,它在某些情況下可以在初始化階段之後再開始,這是為了支持JAVA語言的運行時綁定(也稱為動態綁定和晚期綁定)。
初始化的時候執行一些靜態代碼塊,靜態變量等。
2、類加載的過程
包括:加載、連接(驗證、準備、解析)、初始化。
(1)加載:“加載”是“類加載”的過程的一個階段,在加載階段虛擬機需要完成3件事:
a、通過一個類的全限定名來獲取定義此類的二進制字節流。
b、將這個字節流所代表的靜態存儲結構轉換為方法區的運行時數據結構。
c、在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口。
(2)驗證:驗證是連接階段的第一步,這個階段的目的是為了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機的自身安全。
(3)準備:準備階段是正式為類變量分配內存並設置類變量初始值的階段,這些變量所使用的內存都將在方法區中進行分配。首先,這時候進行內存分配的僅包括類變量(被static修飾的變量)。而不包括實例變量。實例變量將會在對象實例化時隨著對象一起分配在java堆中。其次,這裏所說的初始值“通常情況”下是數據類型的零值,假設一個類變量的定義為:
public static int value = 112;
那變量value值在準備階段過後的初始值為0而不是112。因為這時候尚未開始執行任何JAVA方法。而把value賦值為112的public static 指令是程序編譯後,存放於構造器<cinit>()方法 之中,所以把value賦值為112的動作將在初始化階段才會執行。
對於那種不是“通常情況”,而是“特殊情況”的變量:
public static int value = 123;
編譯的時候Javac將會為value生成ConstantValue屬性,在準備階段虛擬機就會根據ConstantValue的設置將value賦值為123,。
(4)解析:解析階段是將虛擬機常量池內的符號引用替換為直接引用的過程。
(5)初始化:類初始化是類加載過程的最後一步,在這個階段,前面的類加載過程中,除了在加載階段用戶應用程序可以通過自定義加載器參與之外,其余動作完全由虛擬機主導和控制。到了初始化階段,才真正開始執行類中定義的Java程序代碼(或者說字節碼)。在準備階段,變量已經賦值過一次系統要求的初始值,而在初始化階段,則根據程序員通過程序制定的主觀計劃去初始化變量和其他資源,或者可以從另外一個角度來表達,初始化階段就是執行類構造器<cinti>()方法的過程。
JVM(三)JVM的ClassLoader類加載器