標籤:
Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體地區分為若干個不同的資料區域。這些地區都有各自的用途,有的地區隨虛擬機器進程啟動而存在,有的地區則依賴使用者線程啟動和結束而建立和銷毀。Java虛擬機器所管理的記憶體將會包括以下幾個運行時資料區域。
程式計數器
程式計數器是一塊較小的記憶體空間,它的作用可以看做是當前線程所執行的位元組碼的行號指標,位元組碼解譯器工作時就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令,分支,迴圈,跳轉,異常處理,線程恢複等基礎功能都需要依賴這個計數器來完成。
由於每個線程都有一個獨立的程式計數器,以保證虛擬機器線上程切換後能恢複到正確的執行位置(使用線程私人記憶體,各線程之間互不影響)。
如果線程當前執行的是JAVA代碼,這個計數器記錄的時正在執行虛擬機器位元組碼指令的地址;如果是Native方法,這個計數器值則為空白。此記憶體地區是唯一一個在Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的地區。
Java虛擬機器棧
與程式計數器一樣,也是線程私人的,生命週期與線程相同。虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法被執行的時候都會同時建立一個棧幀用於儲存局部變數表,操作棧,動態連結,方法出口等資訊。每個方法被調用直到執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。
局部變數表存放了編譯期可知的各種基礎資料型別 (Elementary Data Type)(boolean,byte,char,short,int,float,long,double),對象引用(reference),returnAddress(指向一條位元組碼指令的地址)。
long 和double類型的資料會佔用2個局部變數空間(Slot) ,其他的資料類型只佔一個。局部變數表所需記憶體在編程期間完成分配,當進入一個方法時,這個方法需要的幀中分配多大的局部變數空間是完全確定的,在方法運行期間不會改變局部變數表的大小。
本地方法棧
本地方法棧與虛擬機器棧非常相似。區別是:虛擬機器棧為虛擬機器執行Java代碼(位元組碼)服務,而本地方法棧則是:虛擬機器使用到的Native方法服務。
Java堆
Java堆是被所有線程共用的一塊記憶體地區,在虛擬機器啟動時建立。此記憶體地區唯一目的就是存放對象執行個體,幾乎所有對象執行個體以及數組都
在這裡分配記憶體。(但隨著JIT編譯器的發展與逃逸分析技術的逐漸成熟,棧上分配,標量替換,最佳化技術將會導致一些微妙的變化,所有的對象都在堆上分配變得不是那麼絕對了)
Java堆是垃圾收集管理的主要區域。Java堆可以細分為:新生代和老年代,在細緻一點有:Eden空間,From Survivor空間,To Survivor空間等。如果從記憶體配置的角度看,線程共用的Java堆中可能劃分出多個線程私人的分配緩衝區(Thread Local Allocation Buffer ,TLAB).
方法區(永久代)
方法區和Java堆一樣,是個線程共用的記憶體地區,它用於儲存虛擬機器載入的類資訊,常量,靜態變數,即時編譯器編譯後的代碼等資料。
運行時常量池
運行時常量池是方法區的一部分.Class 檔案中除了由類的版本資訊,欄位,方法,介面等描述資訊外,還有一項資訊是 常量池(Constant Pool Table),用於存放編譯期產生的各種字面量和符號引用
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
java記憶體機制說明(簡單明了)