新生代与老年代
- 弱分代假说(Weak Generational Hypothesis):绝大多数对象都是朝生夕灭的。(新生代)
- 强分代假说(Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象就越难以消亡。(老年代)
新生代和老年代都是堆分配的内存,新生代分为伊甸园区(Eden)和幸存者区(Survivor)。
分代垃圾回收
当产生新对象时,会在伊甸园(Eden)产生,当伊甸园内存不够时,会进行一次Miner GC,先进行可达性分析标记可清除的垃圾,然后把需要的对象(伊甸园与from区域)复制到幸存区(Survivor)to中,然后把伊甸园的垃圾清除后,交换From区与to区的地址,然后未回收的对象的寿命(生命周期,也可以当作垃圾回收次数)加1;
特点
- 对象首先分配在伊甸园区域
- 新生代空间不足时,出发Miner GC,伊甸园和from存活的对象使用copy复制到to中,存活的对象年龄加1并交换from to
- minor GC会引发stop the world,暂停其他用户的线程,等垃圾回收结束,用户线程才恢复运行
- 当新对象过大,新生代区内存不够时,此对象会直接晋升老年代,当老年代也不够时,full gc抢救一下,如果还不够,就会报 OutOfMomery错误。
- 当对象寿命超过阈值时,会晋升到老年代,最大寿命是15(4bit)
- 当老年代空间不足,会先尝试出发minor gc,如果之后空间仍然不足,那么出发full gc,STW的时间会更长
- 新生代上建立一个全局的数据结构(该结构被称为“记忆集”Remembered Set),这个结构把老年代划分成若干小块,标识出老年代的哪一块内存会存在跨代引用。此后当发生Minor GC时,只有包含了跨代引用的小块内存里的对象才会被加入到GCRoots进行扫描。
跨代引用: 假如要现在进行一次只局限于新生代区域内的收集(Minor GC),但新生代中的对象是完全有可能被老年代所引用的,为了找出该区域中的存活对象,不得不在固定的GC Roots之外,再额外遍历整个老年代中所有对象来确保可达性分析结果的正确性,反过来也是一样。遍历整个老年代所有对象的方案虽然理论上可行,但无疑会为内存回收带来很大的性能负担。