深刻理解java虛擬機——內存分配與回收

對象的內存分配,往大方向將,就是在堆上分配(但也可能通過JIT編譯後被拆散爲標量類型並間接地棧上分配),對象主要分配在新生代的Eden區上,若是啓動了本地線程分配緩衝,將按線程優先在TLAB上分配。少數狀況下也可能會直接分配在老年代中,分配的規則並非百分之百固定的,其細節取決於當前使用的是哪種垃圾收集器組合,還有虛擬機中與內存相關的參數的設置。安全

1.對象優先在Eden分配線程

大多數狀況下,對象在新生代Eden區中分配。當Eden區沒有足夠空間進行分配時,虛擬機會發起一次Minor GC。對象

2.大對象直接進入老年代內存

常常出現大對象容易致使內存還有很多空間時就提早觸發垃圾收集以獲取足夠的連續空間來「安置」它們。虛擬機

虛擬機提供了一個-XX:PretenureSizeThreshold參數,令大於這個設置值得對象直接在老年代分配。這樣作的目的是避免在Eden區及兩個Survivor區之間發生大量的內存複製。io

3.長期存活的對象將進入老年代編譯

虛擬機給每一個對象定義了一個對象年齡計數器。若是對象在Eden出生並通過第一次Minor GC後仍然存活,而且能被Survivor容納的話,將被移動到Survivor空間中,而且對象年齡設爲1.對象在Survivor區中每「熬過」一次Minor GC,年齡就增長1,當年齡增長到必定程度(默認15),就會被晉升到老年代中。對象晉升老年代的年齡閾值,能夠經過參數-XX:MaxTenuringThreshold設置。程序

4.動態對象年齡斷定內存分配

爲了能更好地適應不一樣程序的內存情況,虛擬機並非永遠地要求對象的年齡必須達到了MaxTenuringThreshold才能晉升老年代,若是在Survivor空間中相同年齡全部對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象就能夠直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡。移動

5.空間分配擔保

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

相關文章
相關標籤/搜索