JVM加載類的原理

如何加載class文件:

1.利用類加載器將將class文件讀入到內存中,並且爲這個class文件創建一個實例對象(java.lang.class),如果這個類已經被加載過了,就不會再被加載(同一個類的唯一標識:包名+類名)。

2.將類加載完之後,就是進行連接操作。

3.對類進行初始化。

接下來談談各個步驟的詳細內容:

一.類的加載

利用不同的加載器,對不同來源的class文件進行加載,class文件有以下來源:

1,我們打好的jar包

2.   網絡上的class文件

3.從本地文件系統加載的class

類加載器:

根類加載器(bootstrap classLoader):它的底層是採用c++代碼寫的,它其實不是classLoader的子類,它也沒有子類,

因此它其實是不屬於類的加載層級結構的,它完全由jvm來控制的,它負責加載的是java的核心庫,比如說String,system這些核心庫類。

擴展類加載器(extension classLoader):它負責加載的是jre的擴展目錄(java.ext.dirs下的jar包),比如說咱們自己打的jar包。

應用類加載器(system ClassLoader):它負責加載java命令的-classpath選項和java.class.path系統的屬性,它的父類是extentionclassLoader。

而extention classLoader和systemclassLoader都是繼承了urlclassloader,urlclassloader的父類是classLoader,

因此層級關係大概如下:

用戶類加載器->系統類加載器->擴展類加載器

jvm加載類的機制主要是如下幾種:

(1)全盤負責:當一個類加載器加載某個class時,還會去加載它所依賴和引用的class,這些被依賴和引用的class文件其實就是隱式加載的方式。而主動加載的某個class是顯示加載的方式。

(2)父類委託:先讓父類加載器嘗試加載此class文件,如果父類無法加載此class文件,則由當前類加載器去加載此clas文件。

(3)緩存機制:先從緩存區讀取是否存在該class,如果沒有,則利用加載器將其加載成class對象,然後存到緩存區中。

因此加載類的過程如下:

1.先在緩存區取class對象,如果不存在,則會遞歸請求父類加載器加載此class(用戶類加載器->系統類加載器->擴展類加載器),如果父類加載器無法加載此class,則向下遞歸利用子類加載器加載此class,直到當前類加載器無法加載到class,拋出classnotfindexception,否則返回java.lang.class對象。

二.類的連接

1.驗證:檢查被加載的類是否有正確的內部結構,

2.準備:類加載器階段負責對類的類變量分配內存,並且設置默認初始值

3.解析,將類的二進制數據的符號引用轉化成直接引用。

三.類的初始化

初始化一個類時,假如直接父類沒有初始化,則先初始化其直接父類,,假如類中有初始化語句,則先執行這些初始化語句,

因此類代碼的執行順序大概是這樣子的

父類的靜態代碼塊->子類的靜態代碼塊->父類的初始化代碼塊(在創建對象時隱式執行,且在構造器前執行)->父類的構造函數->子類初始化代碼塊->子類構造函數

因此每次最先執行頂級的java.lang.object,jvm會保證這個類的所有父類被初始化(包括直接父類和間接父類)

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章