理解JVM內存區域有利於更好的java編程,java中最常見的OutOfMemoryError異常就是與JVM的內存區域有關。
JVM內存模型分爲以下5類:
1.程序計數器
2.本地方法棧
3.java虛擬機棧
4.java堆
5.方法區(包括常量池)
以上五個區域還可以再分爲兩大類:線程私有區域和線程共有區域
程序計數器、本地方法棧、java虛擬機棧屬於線程私有區域,java堆和方法區屬於線程共有區域,如下圖所示:
線程私有區域:在線程啓動的時候被初始化,一旦線程結束將會銷燬。
線程共有區域:所有的線程都會訪問到,JVM啓動時被初始化,JVM關閉時被銷燬。
1.程序計數器
在基本的計算機體系結構中,程序計數器跟蹤着指令的執行,就像一個指向當前線程所執行的字節碼行號的指針。當每個線程創建的時候都會創建程序計數器,所以該區域是線程私有的。當線程執行的是native方法,該計數器的值爲空。該區域沒有內存溢出(OutOfMemoryError)異常。
2.java虛擬機棧
JVM棧用於存儲java方法執行的內存模型。每個方法被執行的時候都會創建一個棧幀。
如果線程請求的棧深度大於虛擬機的深度將會拋StackOverflowError
如果虛擬機在動態擴展棧時無法獲取足夠的內存空間將會拋OutOfMemoryError異常
3.本地方法棧
JVM支持本地方法,可以爲每個線程分配本地方法棧。如果本地方法不能被JVM加載就不需要本地方法棧。該區域與JVM棧作用相似也會拋StackOverflowError、OutOfMemoryError異常。
4.方法區
方法區是java堆的一個邏輯部分,相對而言垃圾回收再這個區域比較少。運行時常量池也是方法區的一部分。當方法區無法滿足內存分配需求時將會拋OutOfMemoryError異常
5.java堆
堆區域用於存儲實例對象和數組,它被所有線程共享,也是垃圾回收器發揮作用的地方。如果堆中沒有內存可分配,將會拋OutOfMemoryError異常
參考:
1.http://javapapers.com/core-java/java-jvm-run-time-data-areas/#Program_Counter_PC_Register