標籤:共用 das 記憶體配置 儲存 變數 依賴 引用 run ons
java虛擬機器定義了若干種程式運行時使用到的運行時資料區
1.有一些是 隨虛擬機器的啟動而建立,隨虛擬機器的退出而銷毀
2.第二種則是與線程一一對應,隨線程的開始和結束而建立和銷毀。
java虛擬機器所管理的記憶體將會包括以下幾個運行時資料區域
PC寄存器
也叫程式計數器(Program Counter Register)是一塊較小的記憶體空間,它的作用可以看做是當前線程所執行的位元組碼的訊號指標。
每一條JVM線程都有自己的PC寄存器
在任意時刻,一條JVM線程只會執行一個方法的代碼。該方法稱為該線程的當前方法(Current Method)
如果該方法是java方法,那PC寄存器儲存JVM正在執行的位元組碼指令的地址
如果該方法是native,那PC寄存器的值是undefined。
此記憶體地區是唯一一個在Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的地區。
Java虛擬機器棧
與PC寄存器一樣,java虛擬機器棧(Java Virtual Machine Stack)也是線程私人的。每一個JVM線程都有自己的java虛擬機器棧,這個棧與線程同時建立,它的生命週期與線程相同。
虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法被執行的時候都會同時建立一個棧幀(Stack Frame)用於儲存局部變數表、運算元棧、動態連結、方法出口等資訊。每一個方法被調用直至執行完成的過程就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。
JVM stack 可以被實現成固定大小,也可以根據計算動態擴充。
如果採用固定大小的JVM stack設計,那麼每一條線程的JVM Stack容量應該線上程建立時獨立地選定。JVM實現應該提供調節JVM Stack初始容量的手段。
如果採用動態擴充和收縮的JVM Stack方式,應該提供調節最大、最小容量的手段。
JVM Stack 異常情況:
StackOverflowError:當線程請求分配的棧容量超過JVM允許的最大容量時拋出
OutOfMemoryError:如果JVM Stack可以動態擴充,但是在嘗試擴充時無法申請到足夠的記憶體去完成擴充,或者在建立新的線程時沒有足夠的記憶體去建立對應的虛擬機器棧時拋出。
本地方法棧
Java虛擬機器可能會使用到傳統的棧來支援native方法(使用Java語言以外的其它語言編寫的方法)的執行,這個棧就是本地方法棧(Native Method Stack)
如果JVM不支援native方法,也不依賴與傳統方法棧的話,可以無需支援本地方法棧。
如果支援本地方法棧,則這個棧一般會線上程建立的時候按線程分配。
異常情況:
StackOverflowError:如果線程請求分配的棧容量超過本地方法棧允許的最大容量時拋出
OutOfMemoryError:如果本地方法棧可以動態擴充,並且擴充的動作已經嘗試過,但是目前無法申請到足夠的記憶體去完成擴充,或者在建立新的線程時沒有足夠的記憶體去建立對應的本地方法棧,那Java虛擬機器將會拋出一個OutOfMemoryError異常。
方法區(Method Area)
方法區是可供各條線程共用的運行時記憶體地區。儲存了每一個類的結構資訊,例如運行時常量池(Runtime Constant Pool)、欄位和方法資料、建構函式和普通方法的位元組碼內容、還包括一些在類、執行個體、介面初始化時用到的特殊方法
方法區在虛擬機器啟動的時候建立。
方法區的容量可以是固定大小的,也可以隨著程式執行的需求動態擴充,並在不需要過多空間時自動收縮。
方法區在實際記憶體空間中可以是不連續的。
Java虛擬機器實現應當提供給程式員或者終端使用者調節方法區初始容量的手段,對於可以動態擴充和收縮方法區來說,則應當提供調節其最大、最小容量的手段。
Java 方法區異常:
OutOfMemoryError: 如果方法區的記憶體空間不能滿足記憶體配置請求,那Java虛擬機器將拋出一個OutOfMemoryError異常。
運行時常量池(Runtime Constant Pool)
運行時常量池是每一個類或介面的常量池(Constant_Pool)的運行時表現形式,它包括了若干種常量:編譯器可知的數值字面量到必須運行期解析後才能獲得的方法或欄位的引用。
運行時常量池是方法區的一部分。每一個運行時常量池都分配在JVM的方法區中,在類和介面被載入到JVM後,對應的運行時常量池就被建立。
在建立類和介面的運行時常量池時,可能會遇到的異常:
OutOfMemoryError:當建立類和介面時,如果構造運行時常量池所需的記憶體空間超過了方法區所能提供的最大記憶體空間後就會拋出OutOfMemoryError
Java堆
在JVM中,堆(heap)是可供各條線程共用的運行時記憶體地區,也是供所有類執行個體和資料對象分配記憶體的地區。
Java堆載虛擬機器啟動的時候就被建立,堆中儲存了各種對象,這些對象被自動管理記憶體系統(Automatic Storage Management System,也即是常說的“Garbage Collector(記憶體回收行程)”)所管理。這些對象無需、也無法顯示地被銷毀。
Java堆的容量可以是固定大小,也可以隨著需求動態擴充,並在不需要過多空間時自動收縮。
Java堆所使用的記憶體不需要保證是物理連續的,只要邏輯上是連續的即可。
JVM實現應當提供給程式員調節Java 堆初始容量的手段,對於可動態擴充和收縮的堆來說,則應當提供調節其最大和最小容量的手段。
Java 堆異常:
OutOfMemoryError:如果實際所需的堆超過了自動記憶體管理系統能提供的最大容量時拋出。
參考資料:
http://chenzhou123520.iteye.com/blog/1585224,(即參考自《深入理解Java虛擬機器——JVM進階特性與最佳實務》)
JVM運行時資料區