標籤:style blog http java 使用 strong 資料 ar
1、程式計數器
是一塊較小的記憶體空間,是唯一一個沒有規定任何OutOfMemoryError情況的地區。
作用:當前線程所執行的位元組碼(.class)的行號指標。位元組碼解譯器工作是通過改變計數器的值來選取下一條需要執行的位元組碼指令,分支、迴圈、跳轉、異常處理、線程恢複等準系統都需要依賴這個計算機完成。
為了線程切換後能恢複到正確的執行位置,每條線程都有一個獨立的程式計數器,各個線程之間的計數器互不影響,隔離儲存區 (Isolated Storage),這類記憶體地區為“線程私人”的記憶體。
2、JAVA虛擬機器棧
與程式計數器一樣,java虛擬機器棧也是線程私人的,生命週期與線程相同。
虛擬機器棧描述的是java方法執行的記憶體模型:每個方法被執行時都會同時建立一個棧幀(Stack Frame)用於儲存局部變數表、操作棧、動態連結、方法出口等資訊。每個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。
局部變數表存放了編譯期可知的各種基礎資料型別 (Elementary Data Type)、對象引用和returnAddress類型(指向了一條位元組碼指令的地址)。局部變數表所需的記憶體空間在編譯期間完成分配,在方法運行期間不會局部變數表的大小。
對這個地區規定了兩種異常:StackOverflowError異常,線程請求的棧深度大於虛擬機器允許的深度;OutOfMemoryError異常,如果虛擬機器棧可以動態擴充,當擴充無法申請到足夠記憶體時。
3、本地方法棧
與虛擬機器棧作用相似,拋出的異常也是那兩個,有些虛擬機器將兩者合二為一。兩者區別:
虛擬機器棧為虛擬機器執行java方法(即位元組碼)服務;本地方法棧為虛擬機器使用Native方法服務。
4、java堆
是java虛擬機器所管理的記憶體中最大的一塊。被所有線程共用,在虛擬機器啟動時建立。
作用:存放對象執行個體及數組。
Java堆是垃圾收集器管理的主要區域。
從記憶體回收角度看,現在的收集器基本都是分代收集演算法,所以java堆細分為:新生代和老年代,再細緻一點分為Eden,From Survivor, To Survivor。
從記憶體配置角度看,線程共用的java堆中可能劃分出多個線程私人的分配緩衝區。
Java堆可以使物理上不連續的記憶體空間,只要邏輯上連續。可以固定大小,可以擴充。現在一般都是可擴充的。
如果堆中沒有記憶體配置或無法擴充,拋出OutOfMemoryError異常。
5、方法區
與堆一樣,由所有線程共用的記憶體地區,不需連續記憶體,可選固定大小或者可擴充大小。還可以選擇不實現垃圾收集,其實這個地區的回收是有必要的,所以一般相對較少地執行垃圾收集。這個地區的記憶體回收目標主要是針對常量池的回收和對類型的卸載
作用:儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等。
如果方法區無法滿足記憶體配置,拋出OutOfMemoryError異常。
6、運行時常量池
是方法區的一部分。
------------摘自《深入理解java虛擬機器 周志明》