007-對象內存分配與回收
一、概述
1.1、圖解
默認的,新生代 ( Young ) 與老年代 ( Old ) 的比例的值為 1:2 ( 該值可以通過參數 –XX:NewRatio 來指定 ),即:新生代 ( Young ) = 1/3 的堆空間大小。老年代 ( Old ) = 2/3 的堆空間大小。
其中,新生代 ( Young ) 被細分為 Eden 和 兩個 Survivor 區域,這兩個 Survivor 區域分別被命名為 from 和 to,以示區分。默認的,Eden : from : to = 8 : 1 : 1 ( 可以通過參數 –XX:SurvivorRatio 來設定 ),即: Eden = 8/10 的新生代空間大小,from = to = 1/10 的新生代空間大小。JVM 每次只會使用 Eden 和其中的一塊 Survivor 區域來為對象服務,所以無論什麽時候,總是有一塊 Survivor 區域是空閑著的。因此,新生代實際可用的內存空間為 9/10 ( 即90% )的新生代空間。
1.2、為什麽會有年輕代
分代的唯一理由就是優化GC性能。如果沒有分代,那所有的對象都在一塊,GC的時候要找到哪些對象沒用,這樣就會對堆的所有區域進行掃描。而我們的很多對象都是朝生夕死的,如果分代的話,我們把新創建的對象放到某一地方,當GC的時候先把這塊存“朝生夕死”對象的區域進行回收,這樣就會騰出很大的空間出來。
1.3、對象分配過程
1》 對象優先在Eden上分配
大多數情況下,對象優先在新生代Eden區域中分配。當Eden內存區域沒有足夠的空間進行分配時,虛擬機將觸發一次 Minor GC(新生代GC)。Minor GC期間虛擬機將Eden區域的對象移動到其中一塊Survivor區域。
年輕代中的對象基本都是朝生夕死的(80%以上),所以在年輕代的垃圾回收算法使用的是復制算法,復制算法的基本思想就是將內存分為兩塊,每次只用其中一塊,當這一塊內存用完,就將還活著的對象復制到另外一塊上面。復制算法不會產生內存碎片。
在GC開始的時候,對象只會存在於Eden區和名為“From”的Survivor區,Survivor區“To”是空的。緊接著進行GC,Eden區中所有存活的對象都會被復制到“To”,而在“From”區中,仍存活的對象會根據他們的年齡值來決定去向。年齡達到一定值(年齡閾值,可以通過-XX:MaxTenuringThreshold來設置)的對象會被移動到年老代中,沒有達到閾值的對象會被復制到“To”區域。經過這次GC後,Eden區和From區已經被清空。這個時候,“From”和“To”會交換他們的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎樣,都會保證名為To的Survivor區域是空的。Minor GC會一直重復這樣的過程,直到“To”區被填滿,“To”區被填滿之後,會將所有對象移動到年老代中。
2》大對象直接進入老年代
所謂大對象是指需要大量連續空間的對象。虛擬機提供了一個XX:PretenureSizeThreshold參數,令大於這個值的對象直接在老年代中分配。
3》長期存活的對象將進入老年代
虛擬機采用分代收集的思想管理內存,那內存回收時就必須能識別那些對象該放到新生代,那些該到老年代中。為了做到這點,虛擬機為每個對象定義了一個對象年齡Age,每經過一次新生代GC後任然存活,將對象的年齡Age增加1歲,當年齡到一定程度(默認為15)時,將會被晉升到老年代中,對象晉升老年代的年齡限定值,可通過-XX:MaxTenuringThreshold來設置。
1.4、Minor GC 和Full GC區別
新生代GC(Minor GC):指發生在新生代的垃圾收集動作,因為對象大多都具備朝生夕滅特性,所以Minor GC非常頻繁,回收速度也比較快。
老年代GC(Major GC / Full GC):指發生在老年代中的GC,出現Major GC後,經常會伴隨至少一次的 Minor GC。Major GC的速度一般會比Minor GC慢10倍以上。
1.5、有關年輕代的JVM參數
1)-XX:NewSize和-XX:MaxNewSize
用於設置年輕代的大小,建議設為整個堆大小的1/3或者1/4,兩個值設為一樣大。
2)-XX:SurvivorRatio
用於設置Eden和其中一個Survivor的比值,這個值也比較重要。
3)-XX:+PrintTenuringDistribution
這個參數用於顯示每次Minor GC時Survivor區中各個年齡段的對象的大小。
4).-XX:InitialTenuringThreshol和-XX:MaxTenuringThreshold
用於設置晉升到老年代的對象年齡的最小值和最大值,每個對象在堅持過一次Minor GC之後,年齡就加1。
007-對象內存分配與回收