Sapphire 算法简要分析

Sapphire 算法简要分析

几个月前为了分析goroutine的垃圾回收去看了Sapphire算法的论文,在博客里面也贴了第一部分的译文,
不过太监了,对此表示遗憾。于是将该篇论文重新看了一遍,然后整理了一下大致思路。个人理解,水平有限
,可能有误还望大家批评指教!

概述

支持并发的语言(多线程等)的垃圾回收工作尤为复杂,大多语言采用了以标记-回收算法为主的回收机制,
然而在并发的环境下,在进行标记回收的过程中,应用程序新生成很多对象,也会对已经存在的对象进行引用,
或是对正在被复制的对象进行更改。所以为了保持垃圾回收的正确,往往需要较为严格的同步,这种同步会
导致所谓的STW(Stop the world)。举个极端的例子,GC的时候为了保证GC正确性,所有线程都必须暂停
下来!这样的例子当然过于极端,虽然回收过程会变得相当简单,但是在实际生产的系统中,往往100ms的
暂停都是难以容忍的。Sapphire算法提供了一种思路,相比传统的做法可以大大减少STW的时间,主要原因
是去掉了读屏障,只使用了写屏障(因为应用程序写的次数要远远低于读的次数,数据库的读写分离也是靠
这点进行的优化)。

内存分区

该算法定义了内存中的3个区域,分别为UCS

U区域,是指Uncollected,在一个回收周期开始之后,内存中新申请的空间。

C区域,是指一个回收周期内,内存中已有的对象,它会在回收期间分为两个子区域:O区域,指Old
,当回收器运行时就已经在内存中的对象;N区域,指New,回收器运行过程中,会复制O区域的一部分对象
到新开辟的N区域

S区域,是指正在运行的各线程的运行栈,由于栈中内存可以自动回收,而且一般都可能会被使用。

三色标记法

标记清楚法一般是指,对堆中没有被正在运行的程序所引用(可以认为是已经没有用的)的对象和被引用的对象
标记颜色,然后删除没有引用的对象,或者将被引用的对象复制到新区域,将所有指向旧对象的指针改到新对象,
然后全部清除旧区域的对象。三色标记法是另一种标记方法(前面说的可以认为是2色标记法),包含3种颜色:

白色:白色是不可达对象(这种对象要被清除掉);黑色:黑色代表该对象自身是被强引用,而且自身的子引用
也被处理过了(这种对象就是要被留着的);灰色:灰色代表该对象自己是被强引用,但是子引用还没有被处理
(这是一个中间状态,它最终会变成黑色,但它的子引用和孙引用等不一定是黑色)。

三色标记法有一个原则,永远不许黑色的对象指向白色的对象。

标记阶段

标记阶段分为3个步骤,预标记阶段来安装标记阶段的写屏障,根标记阶段处理非栈中的所有引用树的
根然后再经过堆栈标记阶段来完成标记。

  1. 预标记阶段

这个阶段安装一个写屏障,类似于以下形式:

// Mark Phase Write Barrier
//  this is only for pointer stores
//      the update is *p = q
//      the p slot may be in U or O
//      the q object may be in U or O
mark-phase-write(p, q) {
    *p = q;
    mark-write-barrier(q);
}
mark-write-barrier(q) {
    if (old(q) && !marked(q)) {
        // old && !marked means "white"
        enqueue-object(q);
        <
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值