JVM垃圾回收机制(二)

前言

本篇简单介绍垃圾收集算法的分代理论,目前主流垃圾收集器都遵循了“分代收集”(Generational Collection)理论。

假说基础

分代收集名为理论实则是建立在实际情况的经验法则,它建立在两个分代假说之上:
1) 弱分代假说(Weak Generational Hypothesis):绝大多数对象是朝生夕灭的。
2) 强分代假说(Strong Generational Hypothesis):能够熬过越多次垃圾收集的对象越难以消亡。
这两个假说也奠定了诸多常用垃圾收集器的一致的设计原则:即收集器应该将Java堆划分为不同区域,并根据对象的年龄(熬过垃圾收集的次数)分配到不同的区域之中存储。
3)跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说仅仅占有极少数量。
假说3用来解决下文中分代收集的问题,请继续阅读下文。

分代

1) 如果一个区域中的大多对象是朝生夕灭的,那么这个区域回收时只关注如何保留少量存活对象,而不是标记大多数将要死亡的对象。这样能付出较小的代价,获得较大的空间回收。
2)剩下的难以消除的对象,集中放置于另一个区域,对于这个区域JVM就可以用较低的频率去做垃圾回收,这样不仅做到了空间的合理利用也降低了垃圾回收的时间开销。
一般来说,JVM设计者至少会把Java堆分为新生代(Young Generation)和老年代(Old Generation)两个区域。很明显,上文中提到的存储朝生夕灭对象的区域就是新生代,每次能回收大量空间,而年龄较大对象集中的区域即为老年代。但是对于区域划分来说,依然面临着困境:即对象不是孤立的,对象存在跨区域引用的情况。这个时候如果仅对新生代进行垃圾回收,但是存在新生代对象被老年代对象所引用,那么为了找出存活对象,还需要遍历整个老年代来确保可达性分析的准确性,虽然可行,但是开销太大,所以在这里也就到了假说3,其实对于存在引用关系的对象,应该倾向于同时消亡,或者同时存活。例如:新生代对象被老年代引用,那么就会无法回收,那么它的年龄就会增涨,进而晋升到老年代,这样也就消除了跨代引用。

跨代引用的处理方案

根据假说3,我们不再扫描整个老年代,也不需要浪费空间专门记录每个对象是否存在跨代引用。而只需要在新生代上建立一个全局的数据结构(记忆集,Remembered Set),这个结构吧老年代划分为若干个小块,作用就是标识那块老年代的内存存在跨代引用,而后在新生代GC时,只需要把老年代被引用的小块内的对象加入代GC Root中进行扫描。当然这样避免不了一些开销,但是相对于扫描整个老年代还是划算的。

GC分类

根据对Java堆不同区域的回收,又分为:Minor GC、Major GC、Full GC这样的回收类型。对于不同类型的回收,也将采用与对象存亡特征匹配的收集算法。
一般来说:
Minor GC:指新生代的垃圾收集。
Major GC:指老年代的垃圾收集。(注:目前只有GMS会单独收集老年代。不同资料上的说法也不一样,请根据上下文语意来判断时整堆收集还是老年代收集。)
Mixed GC:指混合收集,收集整个新生代和部分老年代。(注:目前只有G1收集器有这种行为)
Full GC: 整堆收集,收集整个Java堆和方法区。

小结

以上就是整个垃圾收集分代理论的简介,作为Java垃圾收集的基础理论,还是要认真了解一下。也有助于理解后面的垃圾收集算法,以及为什么不同区域的收集会采用不同的垃圾收集算法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值