(JVM 筆記)Java虛擬機器:Java 記憶體管理
程式計數器(Program Counter Register)是一塊較小的記憶體空間,它可以看作是當前執行緒所執行的位元組碼的行號指示器。
- Java 虛擬機器的多執行緒是通過執行緒輪流切換並分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器都只會執行一條執行緒中的指令。
- 為了執行緒切換後能恢復到正確的執行位置,每條執行緒都需要有一個獨立的程式計數器,各條執行緒之間計數器互不影響,獨立儲存,屬於“執行緒私有”記憶體。
- 此記憶體區域是唯一一個在 Java 虛擬機器規範中沒有規定任何 OutOfMemoryError 情況的區域。
2. Java 虛擬機器棧
- 執行緒私有,生命週期與執行緒相同;
- 虛擬機器棧描述的是 Java 方法執行的記憶體模型:每個方法在執行的同時都會建立一個棧幀(Stack Frame)用於儲存區域性變數、運算元棧、動態連結、方法出口等資訊。每一個方法從呼叫直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中入棧到出棧的過程。
- 區域性變量表存放了編譯期可知的各種基本資料型別(double、byte、char等)、物件引用(reference 型別,指向物件起始地址的引用指標,指向一個代表物件的控制代碼或者其他與此物件相關的位置)和 returnAddress型別(指向了一條位元組碼指令的地址)。

- 區域性變量表所需的記憶體空間在編譯期間完成分配,當進入一個方法時,這個方法需要在幀中分配多大的區域性變數空間是完全確定的,在方法執行期間不會改變區域性變量表的大小。
3. 本地方法棧
- 本地方法棧(Native Method Stack)與虛擬機器所發揮的作用是非常相似的,本地方法棧為虛擬機器使用到的 Native 方法服務。
4. Java 堆
Java 堆(Java Heap)是 Java 虛擬機器所管理的記憶體中最大的一塊,被所有的執行緒所共享,在虛擬機器啟動時建立,幾乎所有的物件例項都在這裡分配記憶體。(所有的物件例項以及陣列都要在堆上分配,但是,隨著技術發展,所有物件都分配在堆上也漸漸變得不是那麼“絕對”了)。

- Java 堆是垃圾收集器管理的主要區域,也被稱為 “GC 堆” (Garbage Collected Heap)。
- 從記憶體回收角度看,Java 堆可以細分為:新生代和老年代;再細緻一點的有 Eden 空間、From Survivor 空間、To Survivor 空間等。
- 從記憶體分配角度看,執行緒共享的 Java 堆可能劃分出多個執行緒私有的分配緩衝區(Thread Local Allocation Buffer, TLAB)。
- Java 堆可以處於物理上不連續的記憶體空間中,只要邏輯上是連續的即可。