1. 程式人生 > >jvm學習 - 記憶體模型(1)

jvm學習 - 記憶體模型(1)

介紹

如圖,這是jvm執行時的資料分析。以下分別介紹各個資料區域的作用

程式計數器

程式計數器是jvm較小的一塊記憶體空間,可以看作當前執行緒所執行的位元組碼的行號指示器。程式計數器是執行緒私有的記憶體(java虛擬機器多執行緒是通過執行緒輪流切換並分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器只會執行一條執行緒中的指令,因此,為了執行緒切換後能恢復到正確的執行位置,每個執行緒都需要有自己獨立的程式計數器,各個執行緒之間的計數器互不影響,獨立儲存)。

JAVA虛擬機器棧

java虛擬機器棧也是執行緒私有的,它的生命週期和執行緒一樣,虛擬機器棧描述的是java方法執行的記憶體模型:每個方法執行時都會建立一個棧幀用於儲存區域性變量表,運算元棧,動態連結,方法出口等資訊。每一個方法從呼叫到執行完成,都意味著一次棧幀的入棧和出棧操作。

本地方法棧

本地方法棧的作用類似於java虛擬機器棧,唯一的區別在於虛擬機器棧執行的java方法,本地方法棧則為虛擬機器使用到的Native方法(非java語言)服務。

方法區

方法區是執行緒共享的記憶體區域,主要用於儲存虛擬機器載入的類資訊(所以所有的new關鍵字建立例項時,都需要從方法區獲取對應的類資訊),常量(final),靜態變數(static),即時編譯器編譯後的程式碼等資料。當方法區無法滿足記憶體分配需求時,則丟擲OutOfMemoryError異常。在HotSpot虛擬機器中,用永久代來實現方法區,將GC分代收集擴充套件至方法區,但是這樣容易遇到記憶體溢位的問題。

    JDK1.7中,已經把放在永久代的字串常量池移到堆中。

             JDK1.8撤銷永久代,引入元空間。

和方法區一樣,屬於執行緒共享的記憶體區域。在虛擬機器啟動的時候建立,此儲存區域的唯一的目的就是存放物件例項。同時java堆也是垃圾收集器管理的主要區域,因此也被稱為GC堆(Garbage Collected Heap)。Hotspot虛擬機器(不清楚其他虛擬機器)將堆分為新生代和老年代,在細緻一點的就是Eden,From Survivor,To Survivor,老年代。from和to兩個記憶體區域嚴格說大小是相等的。

 

 

新物件會首先分配在Eden中(如果物件過大,比如大陣列,將會直接放到老年代<eden space剩餘空間不足分配,且需要分配物件記憶體大小不小於eden space總空間的一半>)。在GC中,Eden中的物件會被移動到survivor中,直至物件滿足一定的年紀(定義為熬過minor GC的次數),會被移動到老年代。

新生代 ( Young ) 與老年代 ( Old ) 的比例的值為 1:2 ( 該值可以通過引數 –XX:NewRatio 來指定 )
預設的,Eden : from : to = 8 : 1 : 1 ( 可以通過引數 –XX:SurvivorRatio 來設定 ),即: Eden = 8/10 的新生代空間大小,from = to = 1/10 的新生代空間大小。