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