日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java虚拟机类加载机制浅谈_浅谈Java虚拟机(三)之类加载机制

發(fā)布時間:2023/12/10 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java虚拟机类加载机制浅谈_浅谈Java虚拟机(三)之类加载机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在《淺談Java虛擬機》這篇文章中,我們提到了JVM從操作系統(tǒng)方面來說,可以將其看做是一個進程,分別有類加載器子系統(tǒng),執(zhí)行引擎子系統(tǒng)和垃圾收集子系統(tǒng)。這一篇文章就簡單的來談一下類加載器子系統(tǒng)中的類加載機制。

第一:什么叫做類加載機制

就是JVM把.class字節(jié)碼文件加載到內(nèi)存中,并對其數(shù)據(jù)進行校驗、準備、解析和初始化,最終形成能夠被JVM可以直接拿來使用的java類型的一個過程,叫做類加載。如圖示:

1:加載

(1)將.class字節(jié)碼文件加載到內(nèi)存中

(2)將靜態(tài)數(shù)據(jù)結(jié)構(gòu)(即數(shù)據(jù)存在于.class字節(jié)碼文件的結(jié)構(gòu))轉(zhuǎn)化為方法區(qū)(詳見《淺談Java虛擬機(二)》)中運行時的數(shù)據(jù)結(jié)構(gòu)(即數(shù)據(jù)存在于JVM時的數(shù)據(jù)結(jié)構(gòu))

(3)在堆中生成一個代表這個類的java.lang.Class對象,作為數(shù)據(jù)訪問的入口

(4)有一些類是已經(jīng)提前就被加載到了JVM中的,無需等到運行加載時才加載

2:連接

連接就是講java類的二進制代碼合并到java的運行狀態(tài)的過程

(1)驗證:確保加載的類符合JVM的規(guī)范與安全

(2)準備:為static變量在方法區(qū)中分配空間,設(shè)置變量的初始值。例如 static int a = 6,在此階段會將a被初始化為0。(此處特別注意:如果是 static final int a = 6,那么會在此階段將a的值初始化為6)

(3)解析:JVM將常量池中的符號引用轉(zhuǎn)化為直接引用。例如 "abc"為常量池中的一個值,直接會將"abc"替換成存在于內(nèi)存中的地址。

1)符號引用:符號引用與虛擬機實現(xiàn)的內(nèi)存布局無關(guān),引用的目標并不一定已經(jīng)加載到內(nèi)存中。它是以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能無歧義的定位到目標即可。

2)直接引用:直接引用可以是直接指向目標的指針、相對偏移量或是一個能間接定位到目標的句柄。直接引用是與虛擬機實現(xiàn)的內(nèi)存布局相關(guān)的,如果有了直接引用,那么引用的目標必定已經(jīng)在內(nèi)存中存在。

3:初始化

初始化階段是類加載最后一個階段,前面的類加載階段之后,除了在加載階段可以自定義類加載器以外,其它操作都由JVM主導。到了初始階段,才開始真正執(zhí)行類中定義的Java程序代碼。

初始化階段是執(zhí)行類構(gòu)造器方法的過程,方法是由編譯器自動收集類中的類變量的賦值操作和靜態(tài)語句塊中的語句合并而成的。虛擬機會保證方法執(zhí)行之前,父類的方法已經(jīng)執(zhí)行完畢。

4:使用--- 正常使用

5:卸載 ---GC把無用對象從內(nèi)存中卸載

第二:類加載與初始化時機

1:類加載時機

當應用程序啟動的時候,因為內(nèi)存資源有限,為避免影響應用程序的正常運行,所有的類是不會被一次性加載的。

當User user = new User()的時候,一個類真正被加載的時機是在創(chuàng)建對象的時候,才會去執(zhí)行以上的五個過程,去加載類。大家都知道,java中的main方法是程序的入口,所以它最先加載的是擁有main方法的主線程的所在類。

2:類初始化時機

(1)主動引用(有類初始化過程)

1)new 一個對象。

2)調(diào)用類的靜態(tài)成員(除了final常量)和靜態(tài)方法

3)通過反射(reflect)對類進行調(diào)用

4) JVM啟動,main方法鎖在類被提前初始化

5)初始化一個類,如果其父類沒有被初始化,則先初始化父類

(2)被動引用(沒有類初始化過程)

1)當訪問一個靜態(tài)變量時,只有真正聲明這個變量的類才會被初始化

2)通過數(shù)組定義類的引用

3)final變量不會觸發(fā)此類的初始化,因為在其編譯階段就會存儲在常量池中

第三:類加載器

虛擬機設(shè)計團隊把加載動作放到JVM外部實現(xiàn),以便讓應用程序決定如何獲取所需的類,JVM提供了3種類加載器:

(1)啟動類加載器(Bootstrap ClassLoader):

負責加載 JAVA_HOME\lib 目錄中的,或通過-Xbootclasspath參數(shù)指定路徑中的,且被虛擬機認可(按文件名識別,如rt.jar)的類

(2)擴展類加載器(Extension ClassLoader):

負責加載 JAVA_HOME\lib\ext 目錄中的,或通過java.ext.dirs系統(tǒng)變量指定路徑中的類庫

(3)應用程序類加載器(Application ClassLoader):

負責加載用戶路徑(classpath)上的類庫

JVM通過雙親委派模型進行類的加載,當然我們也可以通過繼承java.lang.ClassLoader實現(xiàn)自定義的類加載器。

當一個類加載器收到類加載任務,會先交給其父類加載器去完成,因此最終加載任務都會傳遞到頂層的啟動類加載器,只有當父類加載器無法完成加載任務時,才會嘗試執(zhí)行加載任務。

采用雙親委派的一個好處是比如加載位于rt.jar包中的類java.lang.Object,不管是哪個加載器加載這個類,最終都是委托給頂層的啟動類加載器進行加載,這樣就保證了使用不同的類加載器最終得到的都是同樣一個Object對象。

jdk中的ClassLoader的源碼實現(xiàn):protected synchronized Class> loadClass(String name,boolean resolve)throws ClassNotFoundException {// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c ==null) {try {if (parent !=null) {c = parent.loadClass(name,false);}else {c = findBootstrapClass0(name);}}catch (ClassNotFoundException e) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);}2018-06-01 11:38

總結(jié)

以上是生活随笔為你收集整理的java虚拟机类加载机制浅谈_浅谈Java虚拟机(三)之类加载机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。