1.PC寄存器
每個線程有一個PC寄存器,如果不是Native,則PC寄存器包含當前正在執行的Java虛擬機指令的地址,如果是Native則不定義。
2.Stack
線程私有,與線程同時創建的Java Stack。一個JVM Stack保存多個Frame,Frame用來保存局部變量,部分結果,和方法返回值。Stack不一定是連續分配在內存中的。
與Stack相關的異常有
1固定大小的Stack會StackOverflowError
2 動態大小的Stack會OutOfMemoryError。
3.Heap
JVM有一個所有線程共享的Heap。Heap保存類的實例和數組。存儲在Heap裏的內容由GC回收。Heap可以使動態的也可以是固定大小的。它不一定是連續分配在內存中的。
與Heap相關的異常有OutOfMemoryError。
4.方法區
JVM有一個所有線程共享的方法區。方法區類似於UNIX的text segment。它用來保存常數池,Field,方法數據,已經方法的代碼,構造函數(包括類實例化和接口初始化時的特殊方法,<init>和<cinit>)。方法區可以是固定的,也可以使動態的。雖然方法區是Heap的一部分,但是可以選擇不被GC回收或者被壓縮。它不一定是連續分配在內存中的。
與方法區相關的異常有OutOfMemoryError。
<init>表示構造函數,<cinit>表示不帶參數並且是靜態的類或者接口的初始化方法。
5.運行期常數池
加載到內存中的Class文件內常數池Table就是運行期常數池。它包括各種常數,符號,和方法,域的引用。運行期常數池分配在方法區裏。當JVM創建類或接口時,該類或接口的常數池也會加載到內存中。
與常數池相關的異常有OutOfMemoryError。
6.Native方法Stack
JVM可以使用C Stacks支持Native方法。Native方法是非Java語言實現的方法。Native方法Stack也可以用在用C語言或者其他語言實現JVM指令集解釋器上。如果不能使用Native方法或者不依賴於C Stacks的JVM不用提供Native方法Stack。
Native方法Stack在每個線程創建時被線程分配。它可以是固定大小,也可以是動態的。
與Native方法Stack相關的異常有
1固定大小的Stack會StackOverflowError
2 動態大小的Stack會OutOfMemoryError。
6.Frames(翻譯成框架可不好)
一個Frame用來保存數據和部分結果。他也用來執行動態鏈接,返回方法值和調度異常。
每次方法被調用的時候會創建一個新Frame。當方法調用結束時,Frame被Destroy。Frame是JVM 線程Stack的一部分。每個Frame有它自己的本地變量數組,操作數Stack和一個當前方法的運行期常數池的引用(指針)。
本地變量數組的大小和操作數Stack的大小取決於編譯期間與方法代碼。在一個線程內,只能有一個Frame是Active狀態,這個Frame所關聯的方法一定是在運行中,這個Frame叫做當前Frame,它所在的方法叫做當前方法,所在的類叫當前類。
如果當前方法調用另一個方法,或者當前方法結束,這當前Frame停止。
Frame不能被其他線程訪問。
6.1 本地變量
每個Frame有一個本地變量數組。大小取決於方法的代碼。一個變量保存一個boolean, byte, char, short, int, float, 引用,或者返回地址的值。2個變量可以保存一個long 或者double值。
JVM使用本地變量傳遞方法調用的參數。
6.2 操作數Stack
每個Frame保存一個 LIFO Stack作爲操作數Stack。當Frame建立的時候操作數Stack爲空。JVM提供指令加載本地變量中的常量或值到操作數Stack。然後從操作數Stack中取值,計算,返回結果到操作數Stack。操作數Stack也用來準備傳給方法的參數和接受方法的返回結果。
6.3 動態鏈接
每個Frame包含一個當前方法運行期常數池的引用。該引用爲了支持方法代碼的動態鏈接。一個方法是通過符號引用來調用其他方法和方法變量的。動態鏈接將這些符號引用翻譯爲具體的方法引用(地址)。動態鏈接將加載所需的類解析尚未定義的符號。