天天看點

jvm垃圾回收之複制算法——為什麼分兩塊Survivor空間

複制算法的兩塊Survivor空間

概述

在《深入了解Java虛拟機》這本書中,對複制算法有一段這樣的介紹:現在的商業虛拟機大多采用複制算法來收集新生代。複制算法将記憶體分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor空間,當回收時,将Eden和Survivor中還存活的對象複制到另一塊Survivor上,最後清理掉Eden和剛才使用的空間。對虛拟機不是很熟悉的同學,應該會有這樣的疑問:為什麼硬要分成兩塊Survivor空間呢,明明其中一塊跟Eden的功能是一樣的。

複制算法原理  

Survivor區,一塊叫From,一塊叫To,對象存在Eden和From塊。當進行GC時,Eden存活的對象全移到To塊,而From中,存活的對象按年齡值确定去向,當達到一定值(年齡門檻值,通過-XX:MaxTenuringThreshold可設定)的對象會移到年老代中,沒有達到值的複制到To區,經過GC後,Eden和From被清空。

  之後,From和To交換角色,新的From即為原來的To塊,新的To塊即為原來的From塊,且新的To塊中對象年齡加1.

疑問

隻分一塊Survivor區,當進行GC時,先将Survivor區中存活的對象達到年齡值的移入年老代,清除已死亡的對象,後将Eden區中存活的對象移入Survivor區,将Survivor區的對象年齡都加1.這樣與分兩塊Survivor有什麼差別呢,為什麼虛拟機一定要分成兩塊呢?

解答

在查閱百度及和小夥伴讨論後,得出一個結論,有不妥之處或有更好的想法,歡迎指正。

即若隻分一塊Survivor,在清除Survivor區已死亡的對象時,因為此刻的Survivor區還有存活的對象,清除要比分兩塊Survivor麻煩,兩塊的情況,回收時隻需将存活的對象移走,剩下的對象直接清理即可。

另外,分成兩塊Survivor,From和To分工明确,邏輯了解和技術實作較簡單。

梅花香自古寒來

繼續閱讀