JVM快速調優手冊v1.0之三:記憶體分配策略

superjack2發表於2018-05-18

記憶體分配策略

 
JVM快速調優手冊v1.0之三:記憶體分配策略

瞭解GC其中很重要一點就是了解JVM的記憶體分配策略:即物件在哪裡分配和物件什麼時候回收

Java技術體系中所提倡的自動記憶體管理可以歸結於兩個部分:給物件分配記憶體以及回收分配給物件的記憶體。 
我們都知道,Java物件分配,都是在Java堆上進行分配的,雖然存在JIT編譯後被拆分為標量型別並簡介地在棧上進行分配。如果採用分代演算法,那麼新生的物件是分配在新生代的Eden區上的。如果啟動了本地執行緒分配緩衝,將按執行緒優先在TLAB上進行分配。 
事實上,Java的分配規則不是百分百固定的,其取決於當前使用的是哪一種垃圾收集器組合,還有虛擬機器中與記憶體相關的引數的設定。 

簡單來說,物件記憶體分配主要是在堆中分配。但是分配的規則並不是固定的,取決於使用的收集器組合以及JVM記憶體相關引數的設
下面SerialSerial Old收集器做一個記憶體分配和回收的策略總結。

1.物件優先在新生代Eden分配

首先,讓我們來看一下新生代的記憶體分配情況: 
記憶體分配情況: 
JVM記憶體劃分為一塊較大的Eden空間(80%)和兩塊小的Servivor(各佔10%)。當回收時,將EdenSurvivor中還存活的物件一次性採用複製演算法直接複製到另外一塊Servivor空間上,最後清理到院Eden空間和原先的Survivor空間中的資料。 
大多數情況下,物件在新生代Eden區中分配。當Eden區沒有足夠空間進行分配時,JVM將發起一次Minor GC 
在這裡先說明兩個概念:

·         新生代GCMinor GC):指發生在新生代的垃圾收集動作,因為Java物件大多是具有朝生夕滅的特性,所以Minor GC非常頻繁,而且該速度也比較快。

·         老年代GCMajor GC/Full GC):指發生在老年代的GC,出現了Major GC,一般可能也會伴隨著一次Minor GC,但是與Minor GC不同的是,Major GC的速度慢十倍以上。

2.大物件直接進入老年代

我們先對所謂的大物件做一個定義:大物件,這裡指的是需要大量連續記憶體空間的Java物件。最典型的大物件可以是很長的字串和陣列。 
JVM
對大物件的態度: 
大物件對於JVM的記憶體分配來說是十分麻煩的,如果我們將大物件分配在新生代中,那樣子的話很容易導致記憶體還有不少空間時就提前觸發垃圾收集以獲取足夠的連續空間來安置它們。、 
為了避免上述情況的經常發生而導致不需要的GC活動所浪費的資源和時間,可採用的分配策略是將大物件直接分配到老年代中去,虛擬機器中也提供了-XX:PretenureSizeThreshold引數,令大於這個設定值的物件直接在老年代裡面分配內容。

-XX:PretenureSizeThreshold只對SerialParNew收集器有

3.長期存活的物件將進入老年代

JVM採用分代收集的思想來管理記憶體時,為了識別哪些物件應該放在新生代、哪些物件應該放在老年代,JVM給每個物件定義了一個物件年齡計數器。 
物件年齡計數器:如果物件在Eden出生並經過第一次Minor GC後仍然存活,並且能被Survivor容納的話,便可以被移動到Survivor空間中,年齡計數器將設定該物件的年齡為1.對於物件在Survivor區每經過一次Minor GC,年齡便增加1歲,當它的年齡增加到一定程度(可透過引數-XX:MaxTenuringThreshold設定)預設15,該物件便會進入到老年代中。成為老年代的物件。

4.動態物件年齡判定

事實上,有的虛擬機器並不永遠地要求物件的年齡必須達到MaxTeruringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有物件大小的總和大於Surivior空間的一半,年齡大於或等於該年齡的物件就可以直接進行老年代,無須等到MaxTeruringThreshold中所要求的年齡。

5.空間分配擔保

在發生Minor GC之前,虛擬機器會先檢查老年代中最大的可用的連續空間是否大於新生代中所有物件總空間,如果這個條件成立,那麼Minor GC可以確保是安全的,如果不成立,則虛擬機器會檢視HandlePromotionFaiure設定值是否允許擔保失敗。如果允許,那麼會繼續檢查老年代最大可用的連續空間是否大於歷次晉升到老年代物件的平均大小,如果大於,將嘗試進行一次Minor GC,儘管這次GC是有風險的;如果小於,或者HandlePromotionFaiure設定不允許冒險,那麼這時就要改為進行一次Full GC 
所謂冒險:也就是說當用來輪轉的Survivor區無法承受新生代中所存活的物件記憶體時,需要老年代進行分配擔保,把Survivor無法容納的物件直接進入老年代中,前提是老年代中

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30089851/viewspace-2120429/,如需轉載,請註明出處,否則將追究法律責任。

相關文章