垃圾收集算法

3.3 垃圾收集算法

  1. 弱分代假说(Weak Generational Hypothesis):绝大多数对象都是朝生夕灭的。

  2. 强分代假说(Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象就越难以消亡。

  3. 跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说仅占极少数。

​ 收集器应该将Java堆划分出不同的区域,然后将回收对象依据其年龄(年龄即对象熬过垃圾收集过程的次数)分配到不同的区域之中存储。显而易见,如果一个区域中大多数对象都是朝生夕灭,难以熬过垃圾收集过程的话,那么把它们集中放在一起,每次回收时只关注如何保留少量存活而不是去标记那些大量将要被回收的对象,就能以较低代价回收到大量的空间;如果剩下的都是难以消亡的对象,那把它们集中放在一块,虚拟机便可以使用较低的频率来回收这个区域,这就同时兼顾了垃圾收集的时间开销和内存的空间有效利用。

​ 在Java堆划分出不同的区域之后,垃圾收集器才可以每次只回收其中某一个或者某些部分的区域——因而才有了“Minor GC”“Major GC”“Full GC”这样的回收类型的划分。

​ 把分代收集理论具体放到现在的商用Java虚拟机里,设计者一般至少会把Java堆划分为新生代(Young Generation)和老年代(Old Generation)两个区域。

​ 新生代中的对象是完全有可能被老年代所引用的,为了找出该区域中的存活对象,不得不在固定的GC Roots之外,再额外遍历整个老年代中所有对象来确保可达性分析结果的正确性,反过来也是一样。(性能负担)

存在互相引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。

如果某个新生代对象存在跨代引用,由于老年代对象难以消亡,该引用会使得新生代对象在收集时同样得以存活,进而在年龄增长之后晋升到老年代中,这时跨代引用也随即被消除了。依据这条假说,我们就不应再为了少量的跨代引用去扫描整个老年代,也不必浪费空间专门记录每一个对象是否存在及存在哪些跨代引用,只需在新生代上建立一个全局的数据结构(该结构被称为“记忆集”,Remembered Set),这个结构把老年代划分成若干小块,标识出老年代的哪一块内存会存在跨代引用。此后当发生Minor GC时,只有包含了跨代引用的小块内存里的对象才会被加入到GC Roots进行扫描。虽然这种方法需要在对象改变引用关系(如将自己或者某个属性赋值)时维护记录数据的正确性,会增加一些运行时的开销,但比起收集时扫描整个老年代来说仍然是划算的。

  • 新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。

  • 老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。

  • 混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。

  • 整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。

3.3.2 标记-清除算法(Mark-Sweep)

  • 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

  • 效率问题:标记和清除的效率都不高

  • 空间问题:标记清除后会产生大量不连续的内存碎片,空间碎片太多可能导致以后在程序运行时需要分配大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集。

3.3.3 复制算法

  • 将内存按容量划分为大小相等两块,每次使用其中的一块,当这一块快用完时,就将还存活着的对象复制到另一块上面,然后把已使用过的内存空间一次清理。

  • 分配时不用考虑内存碎片等复杂情况,实现简单,效率高

  • 缺点是内存缩小为原来的一半,代价高。当对象存活率较高的时候要对对象进行较多的复制,效率会变低。

  • Appel式回收的具体做法是把新生代分为一块较大的Eden空间和两块较小的Survivor空间,每次分配内存只使用Eden和其中一块Survivor。

3.3.4 标记-整理算法

  • 首先标记出所有需要回收的对象,然后让所有·存活的对象都向同一端移动,然后清除掉端边界以外的内存

3.3.5 分代收集算法

  • 老年代:对象存活率高,没有额外空间对他进行分配担保,用标记-清除或者标记-整理

  • 新生代:有大批对象死去,少量存活,用复制算法

3.3.6 Stop The World

  • 移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域,移动存活对象并更新所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用程序才能进行,这样的停顿被称为"STW"

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值