1. 程式人生 > >深入理解java虛擬機器閱讀筆記(一)java記憶體區域

深入理解java虛擬機器閱讀筆記(一)java記憶體區域

1.1  概述

對於java來說,虛擬機器是採用的自動管理記憶體機制,不需要手動去寫delete/free程式碼,但是常在河邊走哪有不溼鞋,程式不可避免會遇到記憶體溢位或洩漏的問題,因此知道記憶體區域分佈情況對於記憶體管理是很有必要的。

1.2  執行時資料區域

java虛擬機器在執行java程式的過程中把它管理的記憶體劃分為若干個區域:程式計數器、虛擬機器棧、本地方法棧、堆區和方法區。

1.2.1  程式計數器

程式計數器是一塊執行緒私有的記憶體空間,指代當前執行緒所執行位元組碼的行號指示器。java虛擬機器的多執行緒是通過執行緒輪流切換並分配處理器的執行時間的方式實現的,對於每個執行緒在執行時都需要有自己的程式計數器,為了執行緒切換恢復後能找到自己正在執行位元組碼的位置。程式計數器中記錄的值,如果執行的是java方法則為位元組碼的指令地址,如果執行的是Native方法則計數器的值為空。

1.2.2  虛擬機器棧

虛擬機器棧也是伴隨執行緒的一塊私有的記憶體空間。虛擬機器棧描述的java方法執行的記憶體模型:方法被呼叫時會建立一個棧幀(區域性變量表、運算元棧、動態連結、方法出口等),每個方法呼叫至完成對應一個棧幀的入棧到出棧。區域性變量表中包括:基本資料型別(byte、short、boolean、char、int、long、float、double)、物件引用(對於HotSpot虛擬機器來說是一個指向物件起始地址的引用,其他虛擬機器可能是執行堆區的一個控制代碼地址)和returnAddress型別(一條位元組碼指令地址)。區域性變量表所需的記憶體時編譯期完成的,64位長度的long和double資料型別會佔用2個Slot,其餘的資料型別只佔用1個Slot。

1.2.3  本地方法棧

本地方法棧和虛擬機器棧很類似也是執行緒私有的,當執行java方法時使用虛擬機器棧,當執行Native方法時使用本地方法棧。

1.2.4  堆區

堆區是一塊執行緒共享的記憶體區域,主要存放物件例項以及陣列。堆區是記憶體管理的主要區域,記憶體回收的角度看,堆區可分為:新生代和老年代;細分的話新生代可分為:Eden空間、From Survivor空間、To Survivor空間。記憶體回收的角度看,可以分為多個執行緒私有的分配緩衝區(Thread Local Allocation Buffer,TLAB)。由於堆區不斷進行著物件的建立和回收,很有可能出現記憶體問題,可以通過(-Xmx:初始堆大小 和-Xms:最大堆大小)來控制。

1.2.5  方法區

方法區也是執行緒共享的記憶體區域,主要有虛擬機器載入的類資訊、常量、靜態變數、及時編譯器編譯後的程式碼。由於方法區儲存內容的關係,垃圾收集行為較少出現。

1.3  java物件

1.3.1  物件的建立

當new一個物件時,首先要判斷這個指令的引數(全限定名)能否在常量池中被找到,檢查(全限定名)代表的類是否已被載入,解析和初始化。如果沒有則要先執行類載入過程。類載入完後,需要分配記憶體,物件所需的記憶體在類載入完就確定了,只需要從記憶體中劃分一塊區域給物件。劃分時要根據記憶體是否規整採用不同的方式(指標碰撞和空閒列表)分配,是否規整又取決於垃圾收集器是否帶有整理過程,像Serial、ParNew等收集器帶有整理過程時採用“指標碰撞”,CMS基於“標記-清除”演算法的採用空閒列表分配。記憶體分配完成後,需要對記憶體空間進行初始化零值以及物件頭的設定,最後才是java物件的初始化操作。

1.3.2  物件的記憶體佈局

物件佈局中分3塊區域:物件頭、例項資料和對齊填充。物件頭分兩部分,第一部分用於儲存物件自身的執行時資料,如雜湊碼、GC分代年齡、鎖狀態標誌、執行緒持有的鎖、偏向執行緒ID、偏向時間戳等;第二部分為型別指標,該指標指代該物件在方法區類元資料的地址,確定這個物件時通過那個類來建立的(不適用於控制代碼訪問物件的方式)。例項資料部分是物件真正儲存的有效資訊,在程式程式碼中定義的這種型別的欄位內容。對齊填充不是必然存在的,由於物件的大小必須是8位元組的整數倍,當例項資料沒有對齊時,需要通過對齊填充來補全。

1.3.3  物件的訪問定位

java程式從棧去的區域性變量表的物件引用(reference)引用堆區的物件時,有兩種方式:控制代碼和直接指標。控制代碼是在堆區建立一塊記憶體作為控制代碼池,存放物件例項資料與型別資料的具體地址資訊,優點是在物件移動時reference引用的控制代碼地址是不會變的;直接指標是reference指向堆區物件的地址,堆區物件中還有一個型別指標指向物件的型別資料,優點是節省了一次指標定位的開銷。