lock free(lock free内存回收)
1、的实现中有一段注释,详细描述了++里几种主流的安全内存回收方法,列表如下:。读高开销/抢占式/死锁。自动回收/线程无关/免于死锁。
2、简单/高速/可拓展。高速/可拓展/阻塞场景可用。性能敏感/读多写少。
3、++标准库中提供了锁和引用计数方案。锁的缺点很明显,无论是哪种锁,在读的时候都会产生较大的开销。
4、引用计数则相对好一些,但每次读取都需要修改引用计数,高并发场景下这样的原子操作也会成为性能瓶颈,毕竟原子加对应的指令也可以看成是微型锁。内核中提供了方法,笔者目前对此还没有太多的了解。
5、本文主要介绍,一种无锁编程中广泛使用的安全内存回收方法,适用于需要高性能读、读多写少的场景。其论文可参考文献1,标准草案可参考文献2,代码实现可参考中的。首先回忆下引用计数的做法:。仔细观察可以发现:。
lock free(lock free内存回收)
1、每一次的读取操作对应引用计数中增加的数值1;当所有的读取操作都完成时引用计数归0,此时内存可以安全回收。总结起来,当对象正在使用时,就不能回收内存。每一个“正在使用”都需要对应一个标记,引用计数使用的标记是计数数值一,对应的原子操作性能问题就成为它无法摆脱的原罪。
2、而使用的标记更为轻巧,一般通过在链表中标记该对象的指针实现,回收时如果发现链表中有对应的指针就不进行内存回收,将标记的复杂度转移到回收部分,也就更适合读多写少的场景。的简单实现,在线执行简单解释下原理。申请读取时,会在对象链表中申请一个空位置,将对象的指针写入该位置中,读取结束时将该位置重新置空即可;而发生更新时,将更新替换下来的旧指针加入退休列表里,退休列表积攒到一定程度时则检查哪些对象已经不在对象链表中,不再使用的则可以执行删除。
3、如果使用实现上述逻辑,你会发现它的执行速度还要高于上述代码。原因在于这里实现的没有使用非对称内存屏障和线程本地存储优化。
4、如果仔细观察,可以发现函数中使用顺序一致性内部屏障,86平台上会翻译为指令,与指令相比也不遑多让。在读多写少的前提下,可以将读写两边的屏障替换为非对称内存屏障,将读部分的开销转移到写部分中。可参考先前内存屏障博文中的介绍。另一方面,的高性能依赖于平台上线程本地存储。
5、单纯使用更新全局的对象链表和退休列表的性能太低,可以使用做为缓冲层,这样大部分时间都是更新本线程的数据。这部分可以参考中的,其中实现了遍历所有线程的黑魔法。
Hi, this is a comment. To get started with moderating, editing, and deleting comments, please visit the Comments screen in the dashboard. Commenter avatars come from Gravatar.