Java核心:類載入和JVM記憶體的分配

來源:互聯網
上載者:User

標籤:jvm   內容   操作   類庫   rt.jar   類型   指令   ade   棧幀   

 

類的載入:

  指的是將class檔案的位元據讀入到運行時資料區(JVM在記憶體中劃分的)

中,並在方法區內建立一個class對象。

類載入器:

  負責載入編譯後的class檔案(位元組碼檔案)到JVM(Java虛擬機器)當中。

而類載入器主要分為以下幾種:

1.Bootstrap class loader (引導類載入器)

  負責載入Java核心類庫。在jre\lib目錄下,包括rt.jar(Java基礎類庫),這些

都是Java的核心類庫。而且這個載入器是由C語言編寫的,所以在Java程式中是擷取

不到的。

2.Extension class loader(擴充類載入器)

  負責載入Java平台下擴充功能的jar包,這些jar包在jre\lib\ext目錄下。這個載入

器由Java語言編寫的。

3.System class loader(系統類別載入器)

  負責載入classpath目錄下的所有類庫,classpath目錄下的class檔案一般

是我們自己寫的java檔案編譯後的。而這個載入器是由Java語言寫的。

 

這些類載入器協同起來完成整個類的載入過程,因此這些類的載入模式基於

”雙親委託模型“。

 

雙親委託模型“:

  程式運行後,編譯器把Java檔案編譯成class檔案後,首先負責載入的是

系統類別載入器,但它不會馬上載入,而是將此任務移送給它的父類載入器擴充

類載入器載入,擴充類載入器也是將此任務移送給引導類載入器載入。

  class檔案到了引導類載入器那,它先判斷能不能載入這個類,如果能,就

載入;不能,移送給其子載入器,以此類推。最終我們編寫的class都會配置在

classpath環境中,所以,這個類載入任務還是由系統類別載入器完成。如果系統

類載入器都不能載入,就拋出ClassNotFoundException。

 

當一個class載入到JVM中,類載入階段已經完成。接下來JVM分配記憶體,對整個

class檔案(檔案裡面都是二進位的彙編命令)進行內容解析(JVM對二進位的命

令逐行解析,交由CPU執行)。

 

記憶體配置:

  JVM運行起來時就給記憶體劃分空間,這塊空間就稱為運行時資料區。

運行時資料區被劃分為以下幾塊內容:

1.棧:

  每一個線程運行起來的時候就會對應一個棧(線程棧),棧中存放的資料被當前

線程所獨享(不會產生資源共用情況,所以線程是安全的)。而棧當中存放的是棧幀,

當線程調用方法時,就是形成一個棧幀,並將這個棧幀進行壓棧操作。方法執行完後,

進行出棧操作。這個棧幀裡麵包括(局部變數,運算元棧,指向當前方法對應類的常

量池引用,方法返回地址等資訊)。

2.本地方法棧:

  本地方法棧的機制和棧的相似,區別在於,棧啟動並執行是Java實現的方法,而本地

方法棧啟動並執行是本地方法。本地方法指的是JVM需要調用非Java語言所實現的方法,

例如C語言。在JVM規範中,沒有強化性要求實現方一定要劃分出本地方法棧(例如:

HotSpot虛擬機器將本地方法棧和棧合二為一)和具體實現(不同的作業系統,對JVM

規範的具體實現都不一樣)。

3.程式計數器:

  程式計數器也可以稱為PC寄存器(通俗講就是  指令緩衝)。它主要用於緩衝當前

程式下一條指令的指令地址,CPU根據這個地址找到將要執行的指令。這個寄存器是JVM

內部實現的,不是物理概念上的計數器,不過和JVM的實現邏輯一樣。

4.堆:

  堆記憶體主要存放建立的對象和數組。堆記憶體在JVM中是唯一的,能被多個線程所共用。

堆裡面的每一個對象都存放著執行個體的執行個體變數。

  當在方法中定義了局部變數,如果這個變數是基礎資料型別 (Elementary Data Type),那麼這個變數的值就直接

存放在棧中;如果這個變數是引用資料類型,那麼變數值就存放在堆記憶體中,而棧中存放的是

指向堆中的引用地址。

5.方法區:

  方法區在JVM也是一個非常重要的一塊記憶體地區,和堆一樣,可以被多個線程多共用。

主要存放每一個載入class的資訊。class資訊主要包含魔數(確定是否是一個class檔案),常量

池,訪問標誌(當前的類是普通類還是介面,是否是抽象類別,是否被public修飾,是否使用了final

修飾等描述資訊......),欄位表集合資訊(使用什麼存取修飾詞,是執行個體變數還是靜態變數,是否

使用了final修飾等描述資訊.....),方法表集合資訊(使用什麼存取修飾詞,是否靜態方法,是否

使用了final修飾,是否使用了synchronized修飾,是否是native方法......)等內容。當一個類加

載器載入了一個類的時候,會根據這個class檔案建立一個class對象,class對象就包含了上述的資訊。

後續要建立這個類的執行個體,都根據這個class對象建立出來的。

6.常量池:

  常量池是方法區中的一部分,存放class對象中最重要的資源。JVM為每一個class對象都維護一個

常量池。它主要儲存兩種類型的常量:

1.字面常量:

  字面常量通常就是在Java中定義的字面量值。例如:int = 1,中的 1,String s = "hello",這個

hello就是字面量。或者使用final修飾的常量值。

2.符號引用:

  符號引用主要包括類和介面的完整類名,屬性的名稱和描述符,方法名和描述符等。

 

 

-----------------------------------------------------------

Java核心:類載入和JVM記憶體的分配

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.