1. 程式人生 > >菜鳥學習JVM——分代回收

菜鳥學習JVM——分代回收

分代回收

上篇文章介紹了幾種垃圾回收的演算法,但這些演算法當中並沒有一個是完美的,可以代替其他所有演算法,他們各自有各自的優勢。因此JVM需要根據垃圾回收物件的特性,選擇合適的回收演算法。

JVM中大部分物件的生命週期非常短,朝生夕滅;還有一些物件,他們的生命週期很長,有的甚至長生不老、壽與JVM齊。於是就有了分代的概念。

分代

  • 新生代(Young Generation
    +Eden
    +Survivor From
    +Survivor To
  • 老年代(Old Generation
  • 永久代(Permanent Generation
![分代](https://img-blog.csdn.net/20160521142806990)
如上面所描述的,JVM將記憶體分成不同的區域。針對新生代和老年代分別才用瞭如下兩種回收方式:
  • Minor Collection(對新生代進行垃圾回收,Hot Spot採用的複製演算法
  • Full Collection(對所有分代進行垃圾回收,也叫Major Collection,Hot Spot採用的是標記-壓縮演算法

回收過程

一般情況下,新產生的物件,會被分配到新生代的Eden( 大物件會直接進入老年代)。當Eden沒有足夠空間的時候,就會進行Minor Collection。在Minor Collection執行的時候,會將存活下來的物件複製到Survivor區。如果Survivor也沒有足夠空間的時候,將會有一部分物件被遷移到老年代,這個遷移的過程稱作晉升(Promotion

)。

隨著Minor Collection的不斷進行,老年代中的物件也會越來越多,當老年代記憶體緊張的時候,就會觸發Full Collection。通常Full Collection會對整個堆進行回收(CMS收集器除外,它不對新生代進行回收)。相比新生代,老年代的回收頻率非常低,因為它每一次回收耗時很長。

JVM會通過以下兩個引數判斷物件是否晉升到老年代:

  • 年齡,經歷Minor Collection的次數代表物件的年齡
  • 大小,即佔用記憶體空間的大小

一些JVM的引數

選項 預設值 作用
-XX:InitialSurvivorRatio 8 新生代Eden/Survivor空間的初始比例
-XX:SurvivorRatio 8 新生代Eden/Survivor空間的比例
-XX:MinSurvivorRatio 3 新生代Eden/Survivor空間的最小比例
-XX:TargetSurvivorRatio 50 垃圾回收後期望的Survivor區空間使用率
-XX:InitialTenuingThreshold 7 晉升到老年代的物件年齡初始閥值
-XX:MaxTenuringThreshold 15 晉升到老年代的年齡閥值
-XX:PretenureSizeThreshold 0 直接晉升老年代的物件大小
-XX:UsePSAdaptiveSurvivorSizePolicy true 自適應調整Survivor區域大小策略

關於JVM調優

我們經常談到JVM調優,JVM也為我們提供了非常多的自定義引數(上表只是跟今天內容比較緊密的一些引數),供我們配置。現實中,我們的軟硬體環境各不相同,實際的需求場景也千差萬別,所以我們很難(說很難是因為嚴謹,其實就沒有)寫出一套放諸四海皆準的配置來。具體的調優方案,還得根據具體的應用,以及工程師的個人經驗和能力來制定。目前小弟能力有限,沒有什麼調優的經驗,所以就不過多的說啦,待日後時機成熟了,一定再跟大家分享。