标记-压缩算法原理及优缺点

背景:

复制算法的高效性是建立在存活对象少,垃圾对象多的前提下的。这种情况在新生代经常发生,但是在老年代,更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活对象数量较多,复制的成本也很高。因此,基于老年代垃圾回收的特性,需要使用其他垃圾回收算法。

标记-清除算法的确可以应用到老年代中,但是该算法不仅执行效率低下,而且在执行完内存回收后还会产生内存碎片,所以JVM的设计者需要在此基础上进行改进。标记-压缩(Mark-Compact)算法由此诞生。

1970年前后,G.L.Steele、 C.J.Chene 和 D.S.Wise等研究者发布标记-压缩算法。在许多现代的垃圾收集器中,都使用了标记压缩算法或其改进版本。

执行过程:

第一阶段和标记清除算法一样,从根节点开始标记所有的引用对象;第二阶段将所有内存对象压缩到内存的一段,按顺序排放。之后清理边界外的所有空间

标记压缩的最终效果等于标记清除算法完成之后在进行一次内存碎片整理,因此,也可以把它称为标记-清除-压缩算法(Mark-Sweep-Compact)算法。

二者的本质差异在与标记-清除算法是一种非移动式的回收算法,标记-压缩是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策。

可以看到,标记的存活对象将会被整理,按照内存地址一次排列,而未被标记的内存会被清理掉。如此一来,当我们给内存对象分配内存时,JVM只需要持有一个对象的内存地址即可,这比维护一个空闲列表显然少了很多开销。

指针碰撞(Bump the pointer)

如果内存空间以规整和有序的方式分布,即已用和未用的内存都各自一边,彼此之间维系着一个记录下一次分配起始点的标记指针,当为新对象分配内存时,只需要通过修改指针的偏移量将新对象分配在第一个空闲内存位置上,这种分配方式就叫做指针碰撞(Bump the Pointer)。

优点:

  • 消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可。
  • 消除了复制算法当中,内存减半的高额代价。

缺点:

  • 从效率上来说,标记-整理算法要低于复制算法。
  • 移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址。
  • 移动过程中,需要全程暂停用户应用程序。即:STW
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值