大多數狀況下,對象在新生代 Eden 區中分配。當 Eden 區沒有足夠空間進行分配時,虛擬機將發起一次 Minor GC。安全
大對象是指須要大量連續內存空間的 Java 對象,如很長的字符串或數據。對象
一個大對象可以存入 Eden 區的機率比較小,發生分配擔保的機率比較大,而分配擔保須要涉及大量的複製,就會形成效率低下。內存
虛擬機提供了一個 -XX:PretenureSizeThreshold 參數,令大於這個設置值的對象直接在老年代分配,這樣作的目的是避免在 Eden 區及兩個 Survivor 區之間發生大量的內存複製。字符串
JVM 給每一個對象定義了一個對象年齡計數器。當新生代發生一次 Minor GC 後,存活下來的對象年齡 +1,當年齡超過必定值時,就將超過該值的全部對象轉移到老年代中去。虛擬機
使用 -XXMaxTenuringThreshold 設置新生代的最大年齡,只要超過該參數的新生代對象都會被轉移到老年代中去。io
若是當前新生代的 Survivor 中,相同年齡全部對象大小的總和大於 Survivor 空間的一半,年齡 >= 該年齡的對象就能夠直接進入老年代,無須等到 MaxTenuringThreshold 中要求的年齡。效率
JDK 6 Update 24 以前的規則是這樣的:
在發生 Minor GC 以前,虛擬機會先檢查老年代最大可用的連續空間是否大於新生代全部對象總空間,
若是這個條件成立,Minor GC 能夠確保是安全的;
若是不成立,則虛擬機會查看 HandlePromotionFailure 值是否設置爲容許擔保失敗,
若是是,那麼會繼續檢查老年代最大可用的連續空間是否大於歷次晉升到老年代對象的平均大小,
若是大於,將嘗試進行一次 Minor GC,儘管此次 Minor GC 是有風險的;
若是小於,或者 HandlePromotionFailure 設置不容許冒險,那此時也要改成進行一次 Full GC。date
JDK 6 Update 24 以後的規則變爲:
只要老年代的連續空間大於新生代對象總大小或者歷次晉升的平均大小,就會進行 Minor GC,不然將進行 Full GC。數據
經過清除老年代中廢棄數據來擴大老年代空閒空間,以便給新生代做擔保。內存分配
這個過程就是分配擔保。