内存分配和回收策略
對象的內(nèi)存分配,大方向上來說就是在堆上分配(但也可能經(jīng)過JIT編譯后被拆散為標(biāo)量類型并間接地棧上分配),主要對象分配在新生代的Eden區(qū),如果啟動了本地分配緩沖,將按照線程優(yōu)先在TLAB(Thread Local Allocation Buffer)上分配。少數(shù)情況下也可能直接分配到老年代中,這些規(guī)則取決于采用的垃收集集器組合,還有虛擬機中與內(nèi)存相關(guān)參數(shù)的設(shè)置。
1.對象優(yōu)先在Eden分配
大多數(shù)情況下,對現(xiàn)在新生代Eden區(qū)中分配,當(dāng)Eden區(qū)沒有足夠空間時,虛擬機將發(fā)起一次Minor GC。
注:新生代GC(Minor GC):指發(fā)生在新生代的垃圾收集動作,因為大多Java對象壽命短暫,所以Minor GC非常頻繁,回收速度快。
老年代GC(Major GC/Full GC):指發(fā)生在老年代的GC,出現(xiàn)了Major GC,經(jīng)常伴隨著至少一次的Minor GC(但并非絕對的,在 Parallel Scavenge收集器的收集策略里就有直接進行Major GC的策略選擇過程),Major GC的速度一般會比Minor GC慢10倍以上。
2.大對象直接進入老年代
大對象是指:需要大量連續(xù)內(nèi)存空間的Java對象,最典型的大對象就是那種很長的字符串以及數(shù)組。虛擬機提供了一個
-XX: PretenureSizeThreshold參數(shù),令大于這個設(shè)置值的對象直接進入老年代,這樣避免了大對象在Eden區(qū)以及兩個Survivor之間發(fā) 生大量的內(nèi)存復(fù)制(復(fù)習(xí):新生代采用復(fù)制算法收集內(nèi)存)。
注:PretenureSizeThreshold參數(shù)只對Serial和PreNew兩款收集器有效,Parallel Scavenge收集器不認識這個參數(shù),
Parallel Scavenge收集器一般不需要設(shè)置,如果用到必須要使用此參數(shù)的場合,可以考慮ParNew+CMS收集器組合。
3.長期存活的對象進入老年代
虛擬機給每個對象定義了一個對象年齡(Age)計數(shù)器,如果對象在Eden出生并經(jīng)過第一次Minor GC后仍然存活,并且能被Survivor 容納的話,將被移動到Survivor空間中,并且年齡設(shè)為1.對象在Survivor中每熬過一次Minor GC,年齡就增加一歲,當(dāng)年齡增加到一定程 度(默認15歲),將會被晉升到老年代。年齡閾值可以通過參數(shù)-XX:MaxTenuringThreshold設(shè)置。
4.動態(tài)對象年齡判定
虛擬機并不是永遠地要求對象的年齡必須達到了MaxTenuringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有對象大 小總和大于Survivor空間的一半,年齡大于或等于該年齡的對象就可以直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡。
5.空間分配擔(dān)保
在發(fā)生Minor GC前,虛擬機會先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對象總空間,如果成立,那么Minor GC可以確保是安全的,如果不是,則虛擬機會查看HandlePromotionFailure設(shè)置值是否允許擔(dān)保失敗。如果允許,那么會繼續(xù)檢查老年代最大可用連續(xù)空間是否大于歷次晉升到老年代對象的平均大小,如果大于,將嘗試者進行一次Minor GC,盡管這次Minor GC是有風(fēng)險的。如果小于,或者HandlePromotionFailure設(shè)置為不允許冒險,那這次也要改為進行一次Full GC。
轉(zhuǎn)載于:https://www.cnblogs.com/jing99/p/6091568.html
總結(jié)
- 上一篇: 我到义乌拿货被忽悠拿了很多货价钱又贵摇控
- 下一篇: 新iPhone XR将推出两种新颜色 芯