JVM快速調優手冊之三: 內存分配策略

JVM快速調優手冊之三: 內存分配策略

瞭解GC其中很重要一點就是了解JVM的內存分配策略:即對象在哪裏分配和對象何時回收。

    Java技術體系中所提倡的自動內存管理能夠歸結於兩個部分:給對象分配內存以及回收分配給對象的內存。

    咱們都知道,Java對象分配,都是在Java堆上進行分配的,雖然存在JIT編譯後被拆分爲標量類型並簡介地在棧上進行分配。若是採用分代算法,那麼新生的對象是分配在新生代的Eden區上的。若是啓動了本地線程分配緩衝,將按線程優先在TLAB上進行分配。

    事實上,Java的分配規則不是百分百固定的,其取決於當前使用的是哪種垃圾收集器組合,還有虛擬機中與內存相關的參數的設置。

    簡單來講,對象內存分配主要是在堆中分配。可是分配的規則並非固定的,取決於使用的收集器組合以及JVM內存相關參數的設定。

    下面Serial和Serial Old收集器作一個內存分配和回收的策略總結。

對象優先在新生代Eden分配

首先,讓咱們來看一下新生代的內存分配狀況

內存分配狀況:將JVM內存劃分爲一塊較大的Eden空間(80%)和兩塊小的Servivor(各佔10%)。當回收時,將Eden和Survivor中還存活的對象一次性採用複製算法直接複製到另一塊Servivor空間上,最後清理到院Eden空間和原先的Survivor空間中的數據。

大多數狀況下,對象在新生代Eden區中分配。當Eden區沒有足夠空間進行分配時,JVM將發起一次Minor GC。
在這裏先說明兩個概念:
  • 新生代GC(Minor GC):指發生在新生代的垃圾收集動做,由於Java對象大可能是具備朝生夕滅的特性,因此Minor GC很是頻繁,並且該速度也比較快。
  • 老年代GC(Major GC/Full GC):指發生在老年代的GC,出現了Major GC,通常可能也會伴隨着一次Minor GC,可是與Minor GC不一樣的是,Major GC的速度慢十倍以上。

大對象直接進入老年代

咱們先對所謂的大對象作一個定義:大對象,這裏指的是須要大量連續內存空間的Java對象。最典型的大對象能夠是很長的字符串和數組。

JVM對大對象的態度:大對象對於JVM的內存分配來講是十分麻煩的,若是咱們將大對象分配在新生代中,那樣子的話很容易致使內存還有很多空間時就提早觸發垃圾收集以獲取足夠的連續空間來「安置」它們。

爲了不上述狀況的常常發生而致使不須要的GC活動所浪費的資源和時間,可採用的分配策略是將大對象直接分配到老年代中去,虛擬機中也提供了**-XX:PretenureSizeThreshold**參數,令大於這個設置值的對象直接在老年代裏面分配內容。
-XX:PretenureSizeThreshold只對Serial和ParNew收集器有效。

長期存活的對象將進入老年代

當JVM採用分代收集的思想來管理內存時,爲了識別哪些對象應該放在新生代、哪些對象應該放在老年代,JVM給每一個對象定義了一個對象年齡計數器。

對象年齡計數器:若是對象在Eden出生並通過第一次Minor GC後仍然存活,而且能被Survivor容納的話,即可以被移動到Survivor空間中,年齡計數器將設置該對象的年齡爲1.對於對象在Survivor區每通過一次Minor GC,年齡便增長1歲,當它的年齡增長到必定程度(可經過參數-XX:MaxTenuringThreshold設置)默認15,該對象便會進入到老年代中。成爲老年代的對象。

動態對象年齡斷定

事實上,有的虛擬機並不永遠地要求對象的年齡必須達到MaxTeruringThreshold才能晉升老年代,若是在Survivor空間中相同年齡全部對象大小的總和大於Surivior空間的一半,年齡大於或等於該年齡的對象就能夠直接進行老年代,無須等到MaxTeruringThreshold中所要求的年齡。

空間分配擔保

在發生Minor GC以前,虛擬機會先檢查老年代中最大的可用的連續空間是否大於新生代中全部對象總空間,若是這個條件成立,那麼Minor GC能夠確保是安全的,若是不成立,則虛擬機會查看HandlePromotionFaiure設置值是否容許擔保失敗。若是容許,那麼會繼續檢查老年代最大可用的連續空間是否大於歷次晉升到老年代對象的平均大小,若是大於,將嘗試進行一次Minor GC,儘管此次GC是有風險的;若是小於,或者HandlePromotionFaiure設置不容許冒險,那麼這時就要改成進行一次Full GC。

所謂冒險:也就是說當用來輪轉的Survivor區沒法承受新生代中所存活的對象內存時,須要老年代進行分配擔保,把Survivor沒法容納的對象直接進入老年代中,前提是老年代中。
相關文章
相關標籤/搜索