分代收集理论从如何判定对象消亡的角度出发,垃圾收集算法可以划分为“引用计数式垃圾收集”(Reference Counting GC)和“追踪式垃圾收集”(Tracing GC)两大类,这两类也常被称作“直接垃圾收集”和“间接 垃圾收集”。 —《深入理解Java虚拟机》
当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”的理论进行设计。分代收集建立在两个分代假说之上:
- 弱分代假说:绝大多数对象都是朝生夕灭的强分代假说:熬过越多次垃圾收集过程的对象就越难以消灭
两个假说又共同奠定了一个设计原则 : 收集器应该将Java堆划分出不同的区域,然后将回收对象根据年龄(熬过垃圾收集过程的次数)分配到不同的区域之中存储。
将分代理论具体放在现在商用的Java虚拟机里,设计者一般至少会把Java堆划分为新生代和老年代两个区域。
为了解决跨代引用的问题,需要对分代收集理论添加第三条经验法则:
跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说仅占极少数。
根据这条假说,我们就不再为了少量跨代引用去遍历老年代,也不用浪费空间专门记录每一个对象是否存在和存在哪些跨代引用。
只需要在新生代上建立一个全局的数据结构(记忆集),这个结构把老年代分成若干小块,表示老年代哪一块存在跨代引用,在出现新生代的GC时,只需要将包含了跨代引用的小块内存中的对象加入到GC Roots进行扫描
存在互相引用关系的两个对象应该是倾向于同时生存或者同时消亡的。如 一个新生代对象存在跨代引用,由于老年代对象难以消亡,导致新生代在收集过程也会存活,随着年龄增长进入老年代,跨代引用也就消失了。
一些名词 部分收集(Partial GC):指目标不是完整收集整个Java堆的垃圾收集,其中又分为: ■新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。 ■老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。目前只有CMS收集器会有单 独收集老年代的行为。另外请注意“Major GC”这个说法现在有点混淆,在不同资料上常有不同所指, 读者需按上下文区分到底是指老年代的收集还是整堆收集。 ■混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。目前只有G1收 集器会有这种行为。 ·整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集标记 - 清除算法
最早最近出的算法,算法分为标记和清除两个阶段: 首先标记出所有需要回收的对象,在标记完成后,统一回收调所有被标记的对象,也能标记存活对象,回收未标记对象。
缺点:
- 执行效率不稳定内存空间的碎片化问题
将内存分成等量的两块,每次只使用其中一块,当一块内存用完后,就将还存活着的对象复制到另外一块上面,然后把已使用过的内存空间清理调。
运行简单,但是可用内存缩小为了原来的一般,内存空间浪费过多。
标记-整理算法标记整理算法标记过程与标记-清除算法相同,但后续是让所有存活对象向内存空间的一端移动,直接清理掉边界以外的内存。
参考资料如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域,移动存活对象并更新 所有引用这些对象的地方将会是一种极为负重的 *** 作,而且这种对象移动 *** 作必须全程暂停用户应用 程序才能进行,这就更加让使用者不得不小心翼翼地权衡其弊端了,像这样的停顿被最初的虚拟机 设计者形象地描述为“Stop The World”。 —来自《深入理解Java虚拟机》
《深入理解java虚拟机》周志明著
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)