lock free数据结构一般来说拥有比基于lock实现的数据结构更高的性能,但是其实现比基于lock的实现更为复杂,需要处理的难题包括预防ABA问题,内存如何重用和回收等。通常,最简单最有效的处理ABA问题的方法是在目标内存区域加入一个tag,每次目标内存区域被更新或者被重用时增加tag。线程最后一次读取目标内存区域后tag没有改变,CAS操作才能成功。比如对于无锁链表来说,目标内存区域就是链表节点。

但是,在目标内存区域中包含tag这种方法,当所有线程都不再需要使用某块内存区域时,没有机制可以检测。这也就导致这块内存区域不能被释放给系统供其他模块使用。hazard pointer可以用来解决这个问题。

hazard pointer的思想:每个线程可以有多个hazard pointer,和实现的lockfree数据结构相关,这些hazard pointer都会被记录到一个全局数组。线程私有的hazard pointer只能被自己修改,但是可以被其它所有线程读。比如5个线程,每个线程3个hazard pointer,那么全局数组有15个元素。一个线程操作无锁数据结构时,先将当前线程要访问的并且可能被别的线程销毁的目标内存区域的指针放在一个全局的地方,然后再检查一下这个指针是否有效,如果有效,后续就可以安全的读写目标内存区域。怎么判断有效?对于不同的数据结构来说,判断的方法不同,后续有例子。当一个线程想回收线程局部freelist中的内存区域时,首先会遍历全局hazard pointer数组,如果freelist中的目标内存区域的指针不在全局hazard pointer 数组中,说明所有线程都不会访问这个内存区域,那么这个线程就可以将这个目标内存区域释放给OS或者给其它模块使用。

以lock free stack为例:

由于Push操作不会访问可能需要被free的节点的内容,所以不需要修改

重点关注Pop操作:

由于第4行会通过指针t来访问t指向的内存区域的内容,所以在第2行,就把t这个指针保护起来,放入这个线程所属的hazard pointer中(对于lock free stack来说,每个线程只需要一个hazard pointer),放入后,再通过第3行来判断t是否有效,如果t不再是栈顶,说明在第1行和第3行之间,别的线程已经成功pop了栈顶,重试。如果t仍然是栈顶,那么第4步用指针t来访问t指向的内存区域中的变量next是安全的,因为t在之前已经放入了hazard pointer中,别的线程在全局hazard pointer数组中能够找到这个hazard pointer,就不会释放这个节点。while 循环退出,所以pop成功,然后将自己的hazard pointer置NULL,表示本线程后续不会再访问这个节点。

参考资料:

Safe Memory Reclamation for Dynamic Lock-Free Objects Using Atomic Reads and Writes

High Performance Dynamic Lock-Free Hash Tables and List-Based Sets

http://en.wikipedia.org/wiki/ABA

Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects

lock free数据结构内存回收技术-hazard pointer的更多相关文章

  1. Btree并发内存回收

    在并发写Btree原理剖析 一文中提到,节点内存回收有可能导致内存突增以及影响写性能.本文将阐述最近对内存回收的改进,多线程可并行回收内存. 回收策略 采用基于版本的机制,Btree全局维护一个版本号 ...

  2. 《深入理解Java虚拟机》学习笔记之内存回收

    垃圾收集(Garbage Collection,GC)并不是Java语言的半生产物,事实上GC历史远比Java久远,真正使用内存动态分配和垃圾收集技术的语言是诞生于1960年的Lisp语言.经过半个世 ...

  3. 风险指针(Hazard Pointer) 内存空间共享模型

    WiredTiger是一种高性能的开源存储引擎,现已在MongoDB中作为内模式应用.WiredTiger支持行存储.列存储两种存储模式,采用LSM Tree方式进行索引记录 WiredTiger支持 ...

  4. Java技术专题之JVM逻辑内存回收机制研究图解版

    一.引言 JVM虚拟机内存回收机曾迷惑了不少人,文本从JVM实现机制的角度揭示JVM内存回收的原理和机制. 一.Java平台逻辑架构 二.JVM物理结构 通过从JVM物理结构图我们可以看到: 1.JV ...

  5. (转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

    http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟 ...

  6. 实现无锁的栈与队列(5):Hazard Pointer

    两年多以前随手写了点与 lock free 相关的笔记:1,2,3,4,质量都不是很高其实(读者见谅),但两年来陆陆续续竟也有些阅读量了(可见剑走偏锋的技巧是多容易吸引眼球).笔记当中在解决内存释放和 ...

  7. 【转】图片缓存之内存缓存技术LruCache、软引用 比较

    每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常,这个问题曾经让我觉得很烦恼,后来终于得到了解决,那么现在就让我和大家一起分享一下吧.这篇博文要讲的图片缓存机制,我接触到的有两钟,一 ...

  8. JVM内存回收机制——哪些内存需要被回收(JVM学习系列2)

    上一篇文章中讨论了Java内存运行时的各个区域,其中程序计数器.虚拟机栈.本地方法栈随线程生灭,且创建时需要多少内存,基本上在译期间就决定的了,所以在内存回收时无需特殊的关注.而堆和方法区则不同,首先 ...

  9. JVM垃圾回收机制与内存回收

    暂时转于:https://blog.csdn.net/qq_27035123/article/details/72857739 垃圾回收机制 GC是垃圾回收机制,java中将内存管理交给垃圾回收机制, ...

随机推荐

  1. 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine() 分类: C# 2014-02-05 17:18 1060人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) [C#小知识]C#中一些易混淆概念总结(三) ------------------------------ ...

  2. 【数组】Minimum Size Subarray Sum

    题目: Given an array of n positive integers and a positive integer s, find the minimal length of a sub ...

  3. redis报Cannot allocate memory错误

    昨天16:27开始将dp的日志使用ELK处理,当时redis使用内存的量不是很大,100M多点,结果今天早上到了一看xshell被关掉了,赶紧将各服务启动起来,elasticsearch启动没有问题, ...

  4. Etcd安全配置之Basic Auth认证

    <中小团队落地配置中心详解>文章中我们介绍了如何基于Etcd+Confd构建配置中心,最后提到Etcd的安全问题时说了可以使用账号密码认证以达到安全访问的目的,究竟该如何开启认证以及怎么设 ...

  5. centos7-安装mysql5.6.36

    本地安装了mysql5.7, 但和springboot整合jpa时会出现 hibernateException, 不知道为什么, 换个mysql5.6版本的mysql,  源码安装, cmake一直过 ...

  6. Java Graphics 图形绘制

    Graphics类提供基本绘图方法,Graphics类提供基本的几何图形绘制方法,主要有:画线段.画矩形.画圆.画带颜色的图形.画椭圆.画圆弧.画多边形.画字符串等. 画线段 drawLine pub ...

  7. nodejs --- 上传文件并保存到磁盘

    先复习下整个请求的过程 const express = require('express'); const static = require('express-static'); const cook ...

  8. django2.1---上下文处理器

    上下文处理器 上下文处理器是可以返回一些数据,在全局模板中都可以使用.比如登录后的用户信息,在很多页面中都需要使用,那么我们可以放在上下文处理器中,就没有必要在每个视图函数中都返回这个对象. 在set ...

  9. HTML5中Access-Control-Allow-Origin解决跨域问题

    www.111cn.net 更新:2015-01-07 编辑:flyfox 来源:转载 跨域在开发中一些是一个比较常见的问题虽然有json或者xml来解决,现在html5开始流行了,我们可以通过Acc ...

  10. SQL查询出某字段不等于某值的行(其中有为NULL的字段)

    表1如下:TBD1100   TBD1101   TBD1102------------------------------------------  1001            水果       ...