1. 程式人生 > >了解java虛擬機---JVM的基本結構(1)

了解java虛擬機---JVM的基本結構(1)

show 擁有 處理 對象 文章 xss 分享 action 啟動

1. JVM的基本結構

技術分享圖片

1.1. 類加載子系統

類加載子系統負責從文件或者網絡中加載Class信息,加載的類信息存放於方法區的內存空間。方法區中可能還會存放運行時常量信息,包括字符串與數字常量。(這部分常量信息是Class文件中常量池部分的內存映射)。

1.2. JAVA堆

JAVA的堆在JVM啟動的時候建立,幾乎所有的Java對象實例都存放於Java堆中。堆空間是所有線程共享的。根據垃圾回收機制的不同,JAVA堆有可能擁有不同的結構。最為常見的一種結構是將整個堆分為新生代和老年代以及持久代。

技術分享圖片

1. 對象的分配

對象首先分配在eden區,在一次Young GC後,如果對象還存活則會進入S0(from)或者S1(to).之後每次Young GC後如果對象存活,它的年齡就會加1,當對象年齡達到一定條件後,就會被認定為是老年對象,從而進入老年代。

package com.hl.heap;

public class SimleHeap {
	public int id;

	public SimleHeap(int id) {
		this.id = id;
	}
	
	public void show(){
		System.out.println("My ID is " + id);
	}
	
	public static void main(String[] args) {
		SimleHeap s1 = new SimleHeap(1);
		SimleHeap s2 = new SimleHeap(2);
		s1.show();
		s2.show();
	}
}

SimpleHeap類的信息存放在方法區,主函數中的s1和s2存放在JAVA棧中,並且指向堆中的兩個實例。

技術分享圖片

1.3. 直接內存

JAVA的NIO允許java程序使用直接內存,直接內存是在JAVA堆外的,直接向系統申請的內存空間。通常訪問直接內存的速度要優於JAVA堆,直接內存適用於頻繁讀寫的場景,直接內存在JAVA堆外,因此它的大小不會直接受限於Xmx指定的最大堆大小的限制,但是JAVA堆和直接內存依然受限於系統的最大內存。

1.4. 垃圾回收系統

垃圾回收器可對方法區、JAVA堆和直接內存進行回收。

1.5. JAVA棧

每個JVM線程都有一個私有的JAVA棧,JAVA棧在線程創建的時候創建。JAVA棧中保存著局部變量、方法參數、同時和JAVA方法的調用、返回密切相關。

1.5.1 函數調用-出入JAVA棧

棧是線程私有的內存空間,線程執行的基本行為是函數調用,每次函數調用的數據都是通過JAVA棧傳遞的。JAVA棧是一塊先進後出的數據結構,只支持出棧入棧兩種操作。在JAVA棧中保存的主要內容為棧幀。每一次函數調用,都會有一個對應的棧幀被壓入JAVA棧,每一個函數調用結束,都會有一個棧幀被彈出JAVA棧。JAVA方法有兩種返回函數的方式,一種是正常的return,一個是拋出異常,不管哪種方式,都會導致棧被彈出。在一個棧中,至少要包含局部變量表、操作數棧和幀數據區幾個部分。JVM提供了-Xss指定線程棧的最大空間,這個參數決定了函數調用的最大深度。

技術分享圖片

JAVA棧的結構

1.5.1.1 局部變量表

它用於保存函數的參數以及局部變量,局部變量表中的變量只在當前函數調用中有效,當函數調用結束後,隨著函數棧幀的銷毀,局部變量表也會隨之銷毀。由於局部變量表在棧幀中,如果函數的參數與局部變量較多,會使得局部變量表膨脹,從而每一次函數調用就會占用更多的棧空間,最終導致函數的嵌套調用次數減少。

1.5.1.2 操作數棧

主要用於保存計算過程中的中間結果,同時作為計算過程中變量的臨時存儲空間。操作數棧也是一個先進後出的數據結構,只支持入棧和出棧兩種操作。

1.5.1.3 幀數據區

幀數據區中保存著返回常量池的指針,方便程序訪問常量池。當函數返回或者出現異常時,虛擬機必須恢復調用者函數的棧幀,並讓調用者函數繼續執行下去,虛擬機必須有一個異常處理表,方便在發生異常時找到處理異常的代碼,因此異常處理表也是幀數據區中重要的一部分。

1.5.1.4 棧上分配

是JVM優化的一項技術,對於哪些線程的私有對象,可以將它們打散分配在棧上,而不是分配在堆上。當函數調用結束後可以自行銷毀,不需要GC介入,從而提高系統性能。

1.6. 方法區

和JAVA堆一樣,方法區是一塊所有線程共享的內存區域。它用於保存系統的類信息,比如類的字段、方法、常量池等,方法區的大小決定了系統可以保存多少個類。在JDK1.7中方法區可以理解為永久區在JDK1.8中永久區被徹底移除,取而代之的是元數據區,元數據區是一塊堆外的內存,與持久區不同的是,如果不指定元數據區大小,虛擬機會消耗系統內存,直到耗盡為止。

1.7. 本地方法棧

本地方法棧和java棧非常類似,最大的不同在於java棧用於java方法的調用,而本地方法棧則用於調用本地方法(dll,so)。

1.8. PC(Program Counter)寄存器

也是每個線程私有空間,Java虛擬機會為每個Java線程創建PC寄存器。在任意時刻,一個Java線程總是在執行一個方法,這個正在被執行的方法稱為當前方法。如果當前方法不是本地方法,PC寄存器就會指向當前正在被執行的指令。如果當前方法是本地方法,那麽PC寄存器的值就是undefined。

1.9. 執行引擎

負責執行虛擬機的字節碼

?版權聲明:本文為【翰林小院】(huhanlin.com)原創文章,轉載時請註明出處!

了解java虛擬機---JVM的基本結構(1)