天天看點

JVM記憶體區域

JVM記憶體區域

程式計數器:

目前線程執行行的行号訓示器,Java虛拟機多線程通過輪流切換并配置設定處理器執行時間,

一個處理器(對于多和處理器來說是一個核心)都隻會一條線程中的指令,為了線程切

換後能恢複到正确的執行位置,每條線程都需要一條獨立的程式計數器,線程之間計數

器互不引響,獨立存儲,稱為線程私有記憶體。虛拟機規範中唯一沒有規定OOM.

虛拟機棧:

線程私有,為虛拟機執行java方法(位元組碼)服務生命周期與線程相同,虛拟機棧描述的

是java方法執行的記憶體子產品:每個方法執行同時會建立一個棧幀用于存儲局部變量表、操

作數棧、動态連結、方法出口等,每一個方法從調用到執行完成過程,對應着一個棧幀在

虛拟機棧中入棧到出棧的過程,規定兩種異常:線程請求的棧深度大于虛拟機所允許的深

度,将抛出StackOverflowError異常,如果虛拟機可動态擴充(目前大部分java虛拟機都

可動态擴充,隻不過java虛拟機規範中也允許固定長度的虛拟機棧),如果擴充時無法申

請到足夠記憶體時,就會抛出OOM.

本地方法棧:

與虛拟機棧發揮的作用非常相似,為虛拟機使用到的Native方法服務,虛拟機規範中對本

地方法棧使用的語言、方式與資料結構沒有強制規定,Sun HostSpot虛拟機把虛拟機棧和

本地方法棧合二為一,本地方法棧區域也會報StackOverflowError和OOM異常

Java堆:

java堆是所有線程共享的一塊記憶體區域,在虛拟機啟動時建立,此記憶體唯一目的就是存放

執行個體對象,幾乎所有的執行個體對象及數組都要在推上配置設定記憶體,對于大多數應用來說java堆

是虛拟機中管理記憶體最大的一塊,java堆是垃圾收集器管理的主要區域,也被稱為GC堆,

從記憶體回收的角度看,由于現代收集器都采用分代收機算法,是以堆中還可以細分為:新

生代和老年代,再細緻一點有Eden空間、From Survivor空間、To Survivor空間,從記憶體

配置設定的角度來看,線程共享的java堆中可能劃分出多個線程私有的配置設定緩沖區,不過無論

怎麼劃分都與存放内容無關,存放的仍然都是對象執行個體,進一步劃分的目的是為了更好的

回收記憶體,或者更快的配置設定記憶體,記憶體大小既可以固定也可以擴充,可通過Xmx和Xms控制,

如果在堆中沒有記憶體完成執行個體配置設定、也無法再擴充将會報出OOM異常。

方法區:

方法區和java堆一樣,是所有線程共享的記憶體區域,它用于存儲被虛拟機加載的類資訊、

常類、靜态變量、即時編譯器編譯後的代碼等資料,在虛拟機規範中方法區被描述為堆的

一個邏輯部分,它有一個别名叫非對,對于習慣在HotSpot虛拟機上開發、部署的開發者來

說,很多人稱方法區為“永久代(permanent Generation)”本質上兩者不等價,永久代有

-XX:MaxPermSize上限容易造成記憶體溢出,方法區無法滿足記憶體配置設定需求時,将抛出OOM異常。

運作時常量池:

運作時常量池是方法區的一部分,class檔案中除了有類的版本、字段、方法、接口等,還有

一項常量池(Constant Pool Table)用于存放編譯器生成的各種字面量和符号引用,這部分

内容将在類加載後進入方法區的運作時常量池存放,運作時常量池受到方法區記憶體的限制,當

常量池無法申請到記憶體時将抛出OOM異常。

直接記憶體:

不在運作時資料區内,不受Java堆記憶體限制,會受到本機總記憶體限制,同樣會抛出OOM異常。

繼續閱讀