11. JVM中的分代回收
1. JVM中的分代回收
分代回收(Generational Collection)是一种基于对象生命周期特性的垃圾回收策略,其核心思想是:大多数对象的生命周期都很短,而存活时间较长的对象通常会继续存活更长时间。
分代回收的基本原理
对象代际划分:将堆内存划分为不同代(Generation),通常分为年轻代(Young Generation)和老年代(Old Generation)
不同频率回收:对年轻代进行更频繁的垃圾回收,而对老年代进行较少频率的回收
晋升机制:存活足够长时间的年轻代对象会被晋升(Promote)到老年代
2. 分代回收算法
2.1 年轻代回收算法
通常使用复制算法(Copying):
内存划分:年轻代分为Eden区和两个Survivor区(From和To)
分配过程:新对象首先分配在Eden区
回收过程:
标记存活对象
将存活对象复制到一个Survivor区(From→To或To→From)
清空Eden和另一个Survivor区
交换From和To的角色
晋升:对象在Survivor区之间经历一定次数(通常15次)的复制后,晋升到老年代
分配过程图示:
对于新生代,内部又被分为了三个区域:
- 伊甸园区Eden,新生的对象都分配到这里
- 幸存者区survivor(分成from和to)
- Eden区,from区,to区 8 : 1 : 1
1. 新对象首先分配在Eden区
2. 当伊甸园内存不足,标记伊甸园与from(现阶段没有)的存活对象
假如咱们在伊甸园区内标记的是 “A对象”,from(现阶段没有)。
3. 将存活对象采用复制算法复制到 to 中,复制完毕后,伊甸园和 from 内存都得到释放
4. 经过一段时间后伊甸园的内存又出现不足,标记eden区域to区存活的对象,将存活的对象复制到from区
假如伊甸园区咱们标记的 “1对象”,to 区标记 “A对象”。
转移后如下:
5. 对象在Survivor区之间经历一定次数(通常15次)的复制后,晋升到老年代(幸存区内存不足或大对象会导致提前晋升)
假如这次 Eden区存货的对象是 “w对象”,Survivor区经历一定次数依旧存活的是 “A对象”。
转移复制后的结果如下:
2.2 老年代回收算法
通常使用标记-清除-整理算法(Mark-Sweep-Compact):
标记阶段:标记所有存活对象
清除阶段:回收未标记的对象空间
整理阶段:将存活对象向一端移动,减少内存碎片
2.3 跨代引用处理
分代回收需要处理跨代引用问题,通常使用记忆集(Remembered Set)或卡表(Card Table)来记录从老年代指向年轻代的引用,避免全堆扫描。
3. 问题总结
3.1 说一下JVM中的分代回收?
堆的区域划分:
- 堆被分为了两份:新生代和老年代【1:2】
- 对于新生代,内部又被分为了三个区域。Eden区,幸存者区survivor(分成from和to)【8:1:1】
对象回收分代回收策略:
- 新创建的对象,都会先分配到eden区
- 当伊甸园内存不足,标记伊甸园与 from(现阶段没有)的存活对象
- 将存活对象采用复制算法复制到to中,复制完毕后,伊甸园和 from 内存都得到释放
- 经过一段时间后伊甸园的内存又出现不足,标记eden区域to区存活的对象,将其复制到from区
- 当幸存区对象熬过几次回收(通常为15次),晋升到老年代(幸存区内存不足或大对象会提前晋升)
3.2 MinorGc、Mixed Gc、FullGc的区别是什么?
- MinorGC【young GC】发生在新生代的垃圾回收,暂停时间短(STW)
- Mixed GC 新生代 +老年代部分区域的垃圾回收,G1 收集器特有
- FullGC:新生代+老年代完整垃圾回收,暂停时间长(STW),应尽力避免
STW(Stop-The-World):暂停所有应用程序线程,等待垃圾回收的完成。
上一篇 下一篇