聊聊ShenandoahGC的Brooks Pointers

本文主要研究一下ShenandoahGC的Brooks Pointershtml

Shenandoah

Shenandoah面向low-pause-time的垃圾收集器,它的GC cycle主要有less

  • Snapshot-at-the-beginning concurrent mark包括Init Mark(Pause)、Concurrent Mark、Final Mark(Pause)
  • Concurrent evacuation(这个阶段用到了Brooks Pointers(object version change with additional atomically changed indirection)进行copy)
  • Concurrent update references (optional)包括Init update Refs(Pause)、Concurrent update Refs、Final update Refs(Pause)
其中Final Mark或者Final update Refs以后均可能进行Concurrent cleanup,进行垃圾回收,reclaims region

Brooks Pointers

G1 GC在evacuation阶段是parallel的,但不是concurrent,ShenandoahGC为了作到concurrent copy使用了Brooks Pointers。wordpress

Rodney A. Brooks在<<Trading Data Space for Reduced Time and Code Space in Real-Time Garbage Collection on Stock Hardware>>这篇论文提出了一种使用forwarding pointer来作到concurrent copy的方案,该方案在全部对象的内存结构上新增一个forwarding pointer,它要么指向对象本身,要么指向在to-region的本身的拷贝

其要点以下:atom

  • evacuation的第一步是拷贝from-region的对象到to-region
  • evacuation的第二步使用CAS改变from-region的对象的forwarding pointer由本身变为指向to-region的拷贝对象
  • evacuation的第三步就是遍历heap,更新引用到to-region的拷贝对象
若是在evacuation期间,其余线程经过旧的引用访问到了from-region的旧对象,它就须要根据旧对象的forwarding pointer找到to-region的拷贝对象;等全部旧对象的引用都更新完以后,后续就能够回收from-region的旧对象

示例代码

concurrent copy

class VersionUpdater<T, V> {
    final AtomicReference<T> ref = ...;
    void writeValue(V value) {
        do {
            T oldObj = ref.get();
            T newObj = copy(oldObj);
            newObj.set(value);
        } while (!ref.compareAndSet(oldObj, newObj));
    }
}
这里使用do while循环,即先拷贝再进行CAS,若是CAS不成功则继续尝试拷贝和CAS

write barriers

stub Write(val, obj, offset) {
    if (evac-in-progress && // in evacuation phase
        in-collection-set(obj) && // target is in from-space
        fwd-ptrs-to-self(obj)) { // no copy yet
        val copy = copy(obj);
        *(copy + offset) = val; // actual write
        if (CAS(fwd-ptr-addr(obj), obj, copy)) {
            return; // success!
        }
    }
    obj = fwd-ptr(obj); // write to actual copy
    *(obj + offset) = val; // actual write
}
在evacuation阶段,对from-region的对象的写操做会触发该对象的evacuation操做( 若是该对象在to-region尚未copy的话)

evacuation

stub evacuate(obj) {
    if (in-collection-set(obj) && // target is in from-space
        fwd-ptrs-to-self(obj)) { // no copy yet
        copy = copy(obj);
        CAS(fwd-ptr-addr(obj), obj, copy);
    }
}
evacuate先判断该对象是否在from-region且在to-region尚未copy,若是知足条件则进行拷贝,而后CAS修改旧对象的forwarding pointer指向拷贝对象

小结

  • Shenandoah面向low-pause-time的垃圾收集器,它在Concurrent evacuation阶段用到了Brooks Pointers(object version change with additional atomically changed indirection)进行copy,以实现concurrent copy
  • Rodney A. Brooks在<<Trading Data Space for Reduced Time and Code Space in Real-Time Garbage Collection on Stock Hardware>>这篇论文提出了一种使用forwarding pointer来作到concurrent copy的方案,该方案在全部对象的内存结构上新增一个forwarding pointer,它要么指向对象本身,要么指向在to-region的本身的拷贝
  • evacuation的第一步是拷贝from-region的对象到to-region;evacuation的第二步使用CAS改变from-region的对象的forwarding pointer由本身变为指向to-region的拷贝对象;evacuation的第三步就是遍历heap,更新引用到to-region的拷贝对象

doc

相关文章
相关标签/搜索