目錄
類別載入機制
加載:
驗證:
準備:
解析:
首頁 Java java教程 Java虛擬機器學習 - 類別載入機制

Java虛擬機器學習 - 類別載入機制

Mar 18, 2017 pm 05:51 PM
java虛擬機

類別載入機制

JVM把class檔案載入的內存,並對資料進行校驗、轉換解析與初始化,最後形成JVM可以直接使用的Java類型的過程就是載入機制。

類別從被載入到虛擬機器記憶體開始,到卸載出記憶體為止,它的生命週期包括了:載入(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization) 、使用(Using)、卸載(Unloading)七個階段,其中驗證、準備、解析三個部分統稱連結。

加載(裝載)、驗證、準備、初始化和卸載這五個階段順序是固定的,類別的載入過程必須按照這種順序開始,而解析階段不一定;它在某些情況下可以在初始化之後再開始,這是為了運行時動態綁定特性。值得注意的是:這些階段通常都是互相交叉的混合式進行的,通常會在一個階段執行的過程中呼叫或啟動另一個階段。


加載:

加載階段是“類加載機制”中的一個階段,這個階段通常也被稱作“裝載”,主要完成:

1.通過“類全名”來獲取定義此類別的二進位位元組流

2.將位元組流所代表的靜態儲存結構轉換為方法區的執行時間資料結構

3.在java堆中產生一個代表這個類別的java.lang.Class對象,作為方法區這些資料的存取入口

虛擬機規範對於「透過「類別全名」來獲取定義此類的二進位位元組流」並沒有指明二進位流必須要從一個本地class檔案中獲取,準確地說是根本沒有指明要從哪裡獲取及怎樣獲取。例如:

從Zip套件中讀取,這很常見,最終成為日後JAR、EAR、WAR格式的基礎。

從網路獲取,常見應用Applet。

運行時計算生成,這種場景使用的最多的就是動態代理技術,在java.lang.reflect.Proxy中,就是用ProxyGenerator.generateProxyClass來為特定介面產生$Prxoy的代理類別的二進位位元組流。

由其他格式檔案生成,典型場景:JSP應用

從資料庫中讀取,這種場景相對少見,有些中間件伺服器(如SAP Netweaver)可以選擇把程式安裝到資料庫中來完成程式碼在集群間的分發。

相對於類別載入過程的其他階段,載入階段(準備地說,是載入階段中獲取類別的二進位位元組流的動作)是開發期可控性最強的階段,因為載入階段可以使用系統提供的類別載入器(ClassLoader)來完成,也可以由使用者自訂的類別載入器完成,開發人員可以透過定義自己的類別載入器去控製位元組流的取得方式。

載入階段完成後,虛擬機器外部的二進位位元組流就按照虛擬機所需的格式儲存在方法區之中,方法區中的資料儲存格式有虛擬機實作自行定義,虛擬機並未規定此區域的具體資料結構。然後在java堆中實例化一個java.lang.Class類別的對象,這個物件作為程式存取方法區中的這些類型資料的外部介面。加載階段與連結階段的部分內容(如一部分字節碼文​​件格式驗證動作)是交叉進行的,加載階段尚未完成,鏈接階段可能已經開始,但這些夾在加載階段之中進行的動作,仍然屬於鏈接階段的內容,這兩個階段的開始時間仍保持固定的先後順序。


驗證:

驗證是連結階段的第一步,這一步是連結的主要訊息機器的要求,且不會危害虛擬機器本身安全。

驗證階段主要包括四個檢驗過程:檔案格式驗證、元資料驗證、字節碼驗證和符號引用驗證。

1.檔案格式驗證 

 驗證class檔案格式規範,例如: class檔案是否已魔術0xCAFEBABE開頭, 主、次版本號是否在目前虛擬機器處理範圍內等

2.元資料驗證

這個這個階段是對字節碼所描述的資訊進行語意分析,以確保起描述的資訊符合java語言規範要求。驗證點可能包括:這個類別是否有父類別(除了java.lang.Object之外,所有的類別都應當有父類別)、這個類別是否繼承了不允許被繼承的類別(被final修飾的)、如果這個類別的父類別是抽象類別,是否實作了起父類別或介面中要求實作的所有方法。

3.字節碼驗證

 進行資料流和控制流分析,這個階段對類別的方法體進行校驗分析,這個階段的任務是確保被校驗類別的方法在運行時不會做出危害虛擬機器安全的行為。如:確保訪法體中的類型轉換有效,例如可以把一個子類物件賦值給父類資料類型,這是安全的,但不能把一個父類物件賦值給子類資料型別、保證跳轉指令不會跳到方法體以外的字節碼命令上。

4.符號參考驗證

符號引用中透過字串描述的全限定名是否能找到對應的類別、符號引用類別中的類,字段和方法的訪問性(private、protected、public、default)是否可被當前類別存取。


準備:

準備階段是正式為類別變數分配記憶體並設定類別變數初始值的階段,這些記憶體都會在方法區中進行分配。這個階段中有兩個容易產生混淆的知識點,首先是這時候進行內存分配的僅包括類變量(static 修飾的變量),而不包括實例變量,實例變量將會在對象實例化時隨著對象一起分配在java堆中。其次是這裡所說的初始值「通常情況」下是資料型別的零值,假設一個類別變數定義為:

public static int value  = 12;

那麼變數value在準備階段過後的初始值為0而不是12,因為此時尚未開始執行任何java方法,而把value賦值為123的putstatic指令是程式被編譯後,存放於類別構造器()方法之中,所以把value賦值為12的動作將在初始化階段才會被執行。

上面所說的「通常情況」下初始值是零值,那相對於一些特殊的情況,如果類別欄位的欄位屬性表中存在ConstantValue屬性,那在準備階段變數value就會被初始化為ConstantValue屬性所指定的值,建置上面類別變數value定義為:

public static final int value = 123;

編譯時javac將會為value產生ConstantValue屬性,在準備階段虛擬機器就會根據ConstantValue的設定將value設定為123。


解析:

 解析階段是虛擬機器常數池內的符號引用替換為直接引用的過程。

符號引用:符號引用是一組符號來描述所引用的目標對象,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標即可。符號引用與虛擬機器實現的記憶體佈局無關,引用的目標物件並不一定已經載入到記憶體中。

直接引用:直接引用可以是直接指向目標物件的指標、相對偏移或是一個能間接定位到目標的句柄。直接引用是與虛擬機器記憶體佈局實現相關的,同一個符號引用在不同虛擬機器實例上翻譯出來的直接引用一般不會相同,如果有了直接引用,那引用的目標必定已經在記憶體中存在。

虛擬機規範並沒有規定解析階段發生的具體時間,只要求了在執行anewarry、checkcast、getfield、instanceof、invokeinterface、invokespecial、invokestatic、invokevirtual、multianewarray、new、putfield和putstatic這13個用於操作符號在引用的字節碼指令之前,先將它們所使用的符號引用進行解析,所以虛擬機器實作會根據需要來判斷,到底是在類別被載入器載入時就對常數池中的符號引用進行解析,還是等到一個符號引用將要被使用前才去解析它。

解析的動作主要針對類別或介面、欄位、類別方法、介面方法四類符號參考進行。分別對應編譯後常數池內的CONSTANT_Class_Info、CONSTANT_Fieldref_Info、CONSTANT_Methodef_Info、CONSTANT_InterfaceMethoder_Info四種常數型別。

1.類別、介面的解析

2.字段解析

3.類別方法解析

4.介面方法解析


初始化: 在準備階段,類別變數已賦過一次系統要求的初始值,而在初始化階段,則是根據程式設計師透過程式製定的主觀計畫去初始化類別變數和其他資源,或者可以從另一個角度來表達:初始化階段是執行類別建構器()方法的過程。在以下四種情況下初始化過程會被觸發執行:

1.遇到new、getstatic、putstatic或invokestatic這4條字節碼指令時,如果類別沒有進行過初始化,則需先觸發其初始化。產生這4條指令的最常見的java程式碼場景是:使用new關鍵字實例化物件、讀取或設定一個類別的靜態欄位(被final修飾、已在編譯器把結果放入常數池的靜態欄位除外)的時候,以及呼叫類別的靜態方法的時候。

2.使用java.lang.reflect套件的方法對類別進行反射調用的時候

3.當初始化一個類別的時候,如果發現其父類別還沒有進行過初始化、則需要先出發其父類的初始化

4.jvm啟動時,使用者指定執行的主類別(包含main方法的那個類別),虛擬機會先初始化這個類別

在上面準備階段public static int value  = 12;  在準備階段完成後value的值為0,而在初始化階呼叫了類別建構器()方法,這個階段完成後value的值為12。

*類別建構子()方法是由編譯器自動收集類別中的所有類別變數的賦值動作和靜態語句區塊(static區塊)中的語句合併產生的,編譯器收集的順序是由語句在來源檔案中出現的順序所決定的,靜態語句區塊中只能存取到定義在靜態語句區塊之前的變量,定義在它之後的變量,在前面的靜態語句快可以賦值,但是不能存取。

*類別建構子()方法與類別的建構子(實例建構子()方法)不同,它不需要明確呼叫父類別建構,虛擬機會保證在子類別( )方法執行前,父類別的()方法已經執行完畢。因此在虛擬機器中的第一個執行的()方法的類別肯定是java.lang.Object。

*由於父類別的()方法先執行,也就表示父類別中定義的靜態語句快要優先於子類別的變數賦值運算。

*()方法對類別或介面來說並不是必須的,如果一個類別中沒有靜態語句,也沒有變數賦值的運算,那麼編譯器可以不為這個類別產生()方法。

*介面中不能使用靜態語句區塊,但介面與類別不太能夠的是,執行介面的()方法不需要先執行父介面的()方法。只有當父介面中定義的變數被使用時,父介面才會被初始化。另外,介面的實作類別在初始化時也一樣不會執行介面的()方法。

*虛擬機會保證一個類的()方法在多線程環境中被正確加鎖和同步,如果多個線程同時去初始化一個類,那麼只會有一個線程執行這個類的 ()方法,其他執行緒都需要阻塞等待,直到活動執行緒執行()方法完畢。如果一個類別的()方法中有耗時很長的操作,那就可能造成多個進程阻塞。

 以上就是Java虛擬機器學習 - 類別載入機制 的內容,更多相關內容請關注PHP中文網(www.php.cn)!

相關文章:

Java虛擬機的具體詳情

深入理解Java虛擬機

Java虛擬機學習物件分配

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

全面指南:詳解Java虛擬機器安裝過程 全面指南:詳解Java虛擬機器安裝過程 Jan 24, 2024 am 09:02 AM

Java開發必備:詳細解讀Java虛擬機器安裝步驟,需要具體程式碼範例隨著電腦科學和技術的發展,Java語言已成為廣泛使用的程式語言之一。它具有跨平台、物件導向等優點,逐漸成為開發人員的首選語言。在使用Java進行開發之前,首先需要安裝Java虛擬機器(JavaVirtualMachine,JVM)。本文將詳細解讀Java虛擬機器的安裝步驟,並提供具體的程式碼示

使用寶塔面板進行Java虛擬機器的最佳化配置 使用寶塔面板進行Java虛擬機器的最佳化配置 Jun 21, 2023 pm 02:52 PM

隨著互聯網的不斷發展,越來越多的應用與業務都需要使用到Java語言開發的程式。而對於Java程式的運行,Java虛擬機器(JVM)的效能就顯得非常重要。因此,進行最佳化配置是提高Java應用程式效能的重要手段。寶塔面板是常用的伺服器控制面板,可以幫助使用者更方便地進行伺服器管理。本文將介紹如何使用寶塔面板對Java虛擬機器進行最佳化配置。第一步:安裝Java虛擬機

Java虛擬機器如何使用引用計數進行記憶體管理? Java虛擬機器如何使用引用計數進行記憶體管理? Apr 13, 2024 am 11:42 AM

Java虛擬機器利用引用計數管理記憶體使用,當物件的引用計數達到0時,JVM會進行垃圾回收。引用計數機制包括:每個物件擁有計數器,儲存指向該物件的參考數量。建立物件時,引用計數器設為1。引用物件時,引用計數器增加。引用結束時,引用計數器減少。

Java虛擬機器中的堆疊幀結構與作用 Java虛擬機器中的堆疊幀結構與作用 Apr 14, 2024 am 08:03 AM

棧幀在Java虛擬機器(JVM)中是執行方法的基礎資料結構,包含以下部分:局部變數表:儲存方法的局部變數。操作數堆疊:存放操作數和中間結果。幀資料:包含返回地址和當前程式計數器。棧幀的作用包括:儲存局部變數。執行操作數操作。處理方法調用。協助異常處理。輔助垃圾回收。

揭秘JVM工作原理:深入探索Java虛擬機器的原理 揭秘JVM工作原理:深入探索Java虛擬機器的原理 Feb 18, 2024 pm 12:28 PM

JVM原理詳解:深入探究Java虛擬機的工作原理,需要具體程式碼範例一、引言隨著Java程式語言的快速發展和廣泛應用,Java虛擬機(JavaVirtualMachine,簡稱JVM)也成為了軟體開發中不可或缺的一部分。 JVM作為Java程式的運作環境,能夠提供跨平台的特性,使得Java程式能夠在不同的作業系統上運作。在本文中,我們將深入探討JVM的工作原

揭秘:Java虛擬機器運作原理與關鍵功能 揭秘:Java虛擬機器運作原理與關鍵功能 Dec 26, 2023 pm 03:58 PM

探究:Java虛擬機器的工作原理與核心功能引言:Java虛擬機器(JavaVirtualMachine,簡稱JVM)是​​Java程式運作的核心部分,它負責將Java原始碼編譯成可執行的字節碼並執行。本文將深入探究Java虛擬機器的工作原理和核心功能,並透過具體的程式碼範例來幫助讀者更好地理解。一、Java虛擬機器的工作原理1.1類別載入器(ClassLoader)J

Java技術的核心要素:深入理解Java語言、Java虛擬機器和Java SE庫 Java技術的核心要素:深入理解Java語言、Java虛擬機器和Java SE庫 Dec 26, 2023 am 10:28 AM

Java核心技術堆疊:深入了解Java語言、Java虛擬機器和JavaSE庫隨著電腦科學和技術的不斷發展,Java語言成為全球最受歡迎的程式語言之一。作為一種跨平台的高階程式語言,Java在各個領域都得到了廣泛應用,尤其是在企業級應用開發和雲端運算領域。要成為優秀的Java開發人員,必須熟練Java核心技術棧,即Java語言、Java虛擬機器和Java

Java虛擬機器的全面安裝與設定指南 Java虛擬機器的全面安裝與設定指南 Jan 05, 2024 pm 02:03 PM

從零開始:Java虛擬機器安裝及設定詳解【導語】Java是一種跨平台的程式語言,其執行平台依賴Java虛擬機器(JavaVirtualMachine,JVM)。透過安裝和設定Java虛擬機,你可以在不同的作業系統上執行Java程式。本文將帶你從零開始,詳細介紹如何安裝和設定Java虛擬機,以及提供一些常用的Java程式碼範例。讓我們開始學習吧! 【第一部分:J

See all articles