JVM 堆內存模型與 GC 策略

Java 中堆內存是 JVM 管理內存中最大的一塊內存,同時又是 GC 管理的重要區域。負載均衡

Java 堆內存主要分紅兩個區域:cdn

1,年輕代。年輕代內部又分紅了兩個區,一個是 Eden 區,一個是 Survivor 區。Survivor 區又劃分紅兩塊,一塊是 from 區,一塊是 to 區;對象

2,老年代。blog

具體一點能夠看圖:生命週期

1、年輕代

IBM 公司的專業研究代表,有將近 98% 的對象是朝生夕死,因此針對這一現狀大多數狀況下,對象會在新生代 Eden 中進行分配,當 Eden 區沒有足夠空間的時候,虛擬機會觸發 Minor GC。內存

Minor GC 的回收速度很快。經過 Minor GC 後,Eden 區會被清空。Eden 區的絕大部分對象在這個時候都會被回收,剩下的那些無需被回收的對象會被放到 Survivor 的 from 區,若是 from 區放不下就直接會被放到 Old 區。虛擬機

等到再次觸發 Minor GC 後會將 Eden 區和 from 區存活的對象放到 to 區。一樣的,若是 To 區放不下就會往 Old 區裏放。等到再下次觸發 Minor GC 後會將 Eden 區和 to 區存活的對象放到 From 區。Minor GC 會將年輕代的存活的數據在 from 區和 to 區來回存放。it

在 Survivor 區中的存活數據,每經歷一次 Minor GC ,這些對象的年齡就會加 1,當長期存活的對象年齡達到 15 歲的時候就會被移到老年代。固然這個 15 ,JVM 支持特殊設置。io

另外還有一個機制,虛擬機並不必定要對象年齡到達 15 歲纔會放入老年代,若是 Survivor 空間中相同年齡對象的大小的和大於 Survivor 空間的一半,年齡大約等於該年齡的對象就能夠直接進入老年區,無需等待「成年」,這點相似於負載均衡。class

2、老年代

老年代佔據着 2/3 的堆內存空間,只有在 Major GC 的時候纔會清理,每次 Major GC 都會觸發 「Stop-The-World」。內存越大,STW 的時間就越長,因此內存也不是越大越好。

除了年輕代那裏的數據會進入老年代以外,還有一種特殊狀況:大對象。大對象是指大量連續內存空間的對象,這部分對象無論其生命週期有多短,都會直接進入老年代。這樣作的目的是爲了不在 Eden 區和兩個 Survivor 區之間發生大量的內存複製。因此必定要注意這些大對象。

相關文章
相關標籤/搜索