lisp 标记形心_标记-压缩算法

标记-压缩垃圾回收算法通过移动可达对象并使其紧凑排列来减少内存碎片。Two-Finger算法适用于固定大小对象,包括两遍遍历:移动对象并更新引用。LISP2算法更通用,处理不同大小对象,需要三次遍历来计算迁移地址、更新引用和实际移动对象。
摘要由CSDN通过智能技术生成

前言

内存碎片一直是非移动垃圾回收器(指在垃圾回收时不进行对象的移动)的一个问题,比如说在前面的标记-清除垃圾回收器就有这样的问题。而标记-压缩垃圾回收算法能够有效的缓解这一问题。

算法原理

既然叫标记-压缩算法,那么它也分为两个阶段,一个是标记(mark),一个是压缩(compact). 其中标记阶段跟标记-清除算法中的标记阶段是一样的,可以参考前面的文章。

而对于压缩阶段,它的工作就是移动所有的可达对象到堆内存的同一个区域中,使他们紧凑的排列在一起,从而将所有非可达对象释放出来的空闲内存都集中在一起,通过这样的方式来达到减少内存碎片的目的。

在压缩阶段,由于要移动可达对象,那么需要考虑移动对象时的顺序,一般分为下面三种:

任意顺序 - 即不考虑原先对象的排列顺序,也不考虑对象间的引用关系,随意的移动可达对象,这样可能会有内存访问的局部性问题。

线性顺序 - 在重新排列对象时,会考虑对象间的引用关系,比如A对象引用了B对象,那么就会尽可能的将A,B对象排列在一起。

滑动顺序 - 顾名思义,就是在重新排列对象时,将对象按照原先堆内存中的排列顺序滑动到堆的一端。

现在大多数的垃圾收集算法都是按照任意顺序或滑动顺序去实现的。下面我们分别来看下它们各自的算法原理。

Two-Finger 算法

Two-Finger算法来自Edwards, 它在压缩阶段移动对象时是任意顺序移动的,它最适用于处理包含固定大小对象的内存区域。由于Mark阶段都是跟标记-清除算法一致的,这里我们只关注Compact阶段。

Two-Finger算法是一个Two Passes算法,即需要遍历堆内存两次,第一次遍历是将堆末尾的可达对象移动到堆开始的空闲内存单元去,第二次遍历则需要修改可达对象的引用,因为一些可达对象已经被移动到别的地址,而原先引用它们的对象还指向着它们移动前的地址。

在这两次遍历过程中,首尾两个指针分别从堆的头尾两个位置向中间移动,直至两个指针相遇,由于它们的运动轨迹酷似两根手指向中间移动的轨迹,因此称为Two Finger算法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值