聊聊ShenandoahGC的Brooks Pointers

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

Shenandoah

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

  • 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。

Rodney A. Brooks在<>这篇论文提出了一种使用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的拷贝对象

如果在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在<>这篇论文提出了一种使用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

转载于:https://juejin.im/post/5c95033c51882574c65204d5

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值