Java虛擬機器的記憶體是如何分佈的

shaozengwei發表於2014-09-29

Java虛擬機器記憶體分為五個區域:方法區,堆,虛擬機器棧,本地方法棧,程式計數器。其中方法區和堆是java虛擬機器共享的記憶體區域,虛擬機器棧,本地方法棧,程式計數器是執行緒私有的。

程式計數器(Program Counter Register)

當前執行緒執行位元組碼的行號指示器。通過改變這個指示器的值來選取下一條需要執行的位元組碼指令。這個記憶體區域是Java虛擬機器唯一一個沒有定義OutOfMemeryError情況的區域。

Java虛擬機器棧(Java Visual Machine Stacks)

虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法執行是都會建立棧幀(Stack Frame)用於儲存區域性變數,操作棧,方法資訊,動態連結,方法出口等資訊。

在java虛擬機器規範中,對於這兩個區域規定了兩種情況的異常:1)如果執行緒請求的棧深度大於虛擬機器所允許的深度將會丟擲StackOverFlowError異常, 2)Java虛擬機器可以動態擴充套件,當無法申請到足夠的記憶體時會丟擲OutOfMemeryError

本地方法棧(Native Method Stacks)

本地方法棧與Java虛擬機器棧非常類似,其區別是Java虛擬機器棧為虛擬機器執行Java方法服務,而本地方法棧是虛擬機器使用到的Native方法服務。

所以本地方法棧也可能出現兩種與Java虛擬機器棧相同的異常。

Java堆(Java Heap)

Java堆是Java虛擬機器管理的最大的一塊記憶體區域,java堆是被所有Java執行緒共享的,在Java虛擬機器啟動時建立,此記憶體的唯一目的就是存放物件例項。幾乎所有的物件例項都要分配在堆中。(隨著JIT編譯器的發展,逃逸分析技術的逐漸成熟,棧上分配,標量替換等優化技術,使得部分物件不再分配在堆上。)

Java堆的大小通過 -Xmx和-Xms兩個引數控制。但是當堆的記憶體再無法擴充套件時,就會出現OutOfMemeryError。

方法區(Method Area)

方法區與Java堆一樣,是各個執行緒共享的記憶體區域,他用於儲存類資訊,常量,靜態變數以及及時編譯後的程式碼等資料。當方法區無法滿足記憶體分配需求時,將丟擲OutOfMemeryError.

相關文章