程序計數器
- 極小的一塊內存空間,可以看做線程所執行的字節碼的行號指示器。
- 線程私有 每個線程都擁有一個獨立的程序計數器。每個線程之間的計數器互相不影響。
- 如果在執行的是一個java方法,那麼計數器記錄的是正在執行的虛擬機的字節碼指令的地址;如果執行的native方法,這個計數器值則爲空。
- 這個區域在java虛擬機規範中 表明了不會出現 OutOfMemoryError情況
java虛擬機棧
- java虛擬機棧 也是線程私有的,生命週期和線程相同。
- 描述了java方法執行的內存模型,每個方法對應一個一個棧幀。
- 棧幀
-
局部變量表
- 存放了各種基本數據類型、對象引用類型,它不同於對象的本身,可能是一個指向對象起始地址的引用指針。
- 64位長度的long 和double 佔用兩個局部變量空間(slot),其餘的數據類型只佔用1個。
- 局部變量表所需的內存空間,在編譯期間完成分配。當進入一個方法需要幀中分配多大的局部變量空間是完全確定的,運行期間不會改變局部變量表的大小。
-
操作數棧
-
動態鏈接
-
方法出口
-
一些附加信息
-
- 如果棧的深度大於虛擬機棧的深度 會拋出StackOverflowError異常。如果虛擬機棧可以動態擴展的話,如果擴展的時候無法申請到足夠的內存,就會拋出OutofMemoryError異常
本地方法棧
- 存儲結構和虛擬機棧一樣,作用也一樣。
- 區別是 虛擬機棧是爲java方法服務,而本地方法棧則爲Native方法服務
- 本地方法棧也會拋出StackOverflowError 和OutofMemoryError 異常
java堆(heap)
- 線程共享的區域,由虛擬機啓動時創建。
- 存放對象實例,幾乎所有的對象實例都在這裏分配內存。
- java堆是垃圾收集器管理的主要區域,因此也稱GC堆。
- java堆分爲新生代、老年代。
- 新生代
- Eden空間,From Survivor空間 To Survivor空間。
方法區(永久代)
- 和java堆一樣 是線程共享的內存區域。
- 存儲JVM 加載的類信息,常量,靜態變量。
- 又稱元空間
運行時常量池
- 屬於方法區的一部分。
- 存放編譯器生成的各種字面量和符號引用,在類加載後進入方法區的運行時常量池存放。
- 會有 OOM異常
直接內存
- 並不屬於JVM運行時數據區的一部分,也不是JVM規範定義的內存
- 也會導致OOM 異常