你的“對象”啥時候會進入老年代?


前言

JVM堆中有新生代老年代兩塊區域,因為使用分代回收策略新生代還會划分為Eden和兩個Survivor區,JVM堆大概是這樣子:

程序運行過程中新產生的對象都會分配在Eden區,隨着時間的推移Eden區也是會滿的,那么這個時候就會進行Minor GC進行清理,清理過程有的對象被清除,有的對象會繼續存活下去。那Java對象啥時候會進入老年代呢?

根據對象年齡

JVM會給對象增加一個年齡(age)的計數器,對象每“熬過”一次GC,年齡就要+1,待對象到達設置的閾值(默認為15歲)就會被移移動到老年代,可通過-XX:MaxTenuringThreshold調整這個閾值。

一次Minor GC后,對象年齡就會+1,達到閾值的對象就移動到老年代,其他存活下來的對象會繼續保留在新生代中。

動態年齡判斷

根據對象年齡有另外一個策略也會讓對象進入老年代,不用等待15次GC之后進入老年代,他的大致規則就是,假如當前放對象的Survivor,一批對象的總大小大於這塊Survivor內存的50%,那么大於這批對象年齡的對象,就可以直接進入老年代了。

如圖上的A、B、D、E這四個對象,假如Survivor 2是100m,如果A + B + D的內存大小超過50m,現在D的年齡是10,那E都會被移動到老年代。實際上這個計算邏輯是這樣的:年齡1 + 年齡2 + 年齡n的多個對象總和超過Survivor區的50%,那就會把年齡n以上的對象都放入老年代。

大對象直接進入老年代

如果設置了-XX:PretenureSizeThreshold這個參數,那么如果你要創建的對象大於這個參數的值,比如分配一個超大的字節數組,此時就直接把這個大對象放入到老年代,不會經過新生代。

這么做就可以避免大對象在新生代,屢次躲過GC,還得把他們來復制來復制去的,最后才進入老年代,這么大的對象來回復制,是很耗費時間的。




《架構文摘》每天一篇架構領域重磅好文,涉及一線互聯網公司應用架構(高可用、高性 能、高穩定)、大數據、機器學習等各個熱門領域。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM