threadsafe

这篇博客文章通过说明我们如何轻松访问线程内存来进行线程安全操作,继续了我在Agrona库上进行的系列文章 。 在继续讨论这是一个相当高级的主题之前,我可能应该警告一下,并且我不尝试解释诸如内存屏障之类的概念,仅概述API的功能。

ByteBuffer的不足

Java提供了一个字节缓冲区类来包装offheap和onheap内存。 字节缓冲区在Java网络堆栈中专门用作从中读取或写入数据的位置。

那么字节缓冲区有什么问题呢? 好吧,因为它们针对用例,所以它们不提供对原子操作之类的支持。 如果要编写可从不同进程同时访问的非堆数据结构,则字节缓冲区无法满足您的需求。 您可能要编写的那种库的一个示例是一个消息队列,一个进程将读取该消息,而另一个进程将写入该消息队列。

Agrona的缓冲器

Agrona提供了几种缓冲区类和接口来克服这些缺陷。 Aeron和SBE库都使用这些缓冲区。

  1. DirectBuffer –顶级接口,可从缓冲区读取值。
  2. MutableDirectBuffer –扩展DirectBuffer添加操作以写入缓冲区。
  3. AtomicBuffer –不,它不是核动力的MutableDirectBuffer ! 该接口添加了原子操作以及比较和交换语义。
  4. UnsafeBuffer –默认实现。 名称unsafe并不意味着不应该使用该类,只是其支持实现使用sun.misc.Unsafe

拆分缓冲区而不是分配单个类的决定是出于希望限制不同系统组件对缓冲区的访问权限的考虑。 如果一个类只需要从一个缓冲区中读取,则不应允许它通过使缓冲区发生突变而将错误引入系统。 同样,不允许设计为单线程的组件使用Atomic操作。

包装一些内存

为了能够使用缓冲区执行任何操作,您需要告诉它缓冲区的起始位置! 此过程称为包装基础内存。 所有包装内存的方法都称为wrap并且可以包装byte[]ByteBufferDirectBuffer 。 您还可以指定用于包装数据结构的偏移量和长度。 例如,这里是包装byte[]

final int offset = 0;final int length = 5;buffer.wrap(new byte[length], offset, length);

包装还有另一个选择–这是存储位置的地址。 在这种情况下,该方法采用存储器的基地址及其长度。 这是为了支持诸如通过sun.misc.Unsafe分配的内存或例如malloc调用之类的事情。 这是使用Unsafe的示例。

final int length = 10;final long address = unsafe.allocateMemory(length);buffer.wrap(address, length);

包装内存还可以设置缓冲区的容量,可以通过capacity()方法进行访问。

存取器

因此,现在您有了可以读取和写入的堆外内存缓冲区。 约定是,每个getter以单词get开头,并以您要获取的值的类型作为后缀。 您需要提供一个地址,以说出要读取的缓冲区中的位置。 还有一个可选的字节顺序参数。 如果未指定字节顺序,则将使用计算机的本机顺序。 这是一个有关如何在缓冲区开始处加长的示例:

final int address = 0;long value = buffer.getLong(address, ByteOrder.BIG_ENDIAN);value++;buffer.putLong(address, value, ByteOrder.BIG_ENDIAN);

除基本类型外,还可以从缓冲区中获取和放入字节。 在这种情况下,要读取或读取的缓冲区作为参数传递。 再次支持byte[]ByteBufferDirectBuffer 。 例如,这是将数据读入byte[]

final int offsetInBuffer = 0;final int offsetInResult = 0;final int length = 5;final byte[] result = new byte[length];buffer.getBytes(offsetInBuffer, result, offsetInResult, length, result);

并发操作

intlong值也可以使用内存排序语义进行读取或写入。 后缀为Ordered方法保证它们最终将被设置为所讨论的值,并且该值最终将在另一个对该值进行易失性读取的线程中可见。 换句话说, putLongOrdered自动执行存储存储内存屏障 。 get*Volatileput*Volatile遵循与在Java中用volatile关键字声明的变量的读写相同的排序语义。

也可以通过AtomicBuffer更复杂的内存操作。 例如,有一个compareAndSetLong ,它将在给定的索引上原子地设置一个更新的值,给定的现有值是一个期望值。 getAndAddLong方法是在给定索引处添加的完全原子的方法。

生活中没有什么是免费的,所有这些都需要警告。 如果您的索引词不对齐,这些保证将不存在。 请记住,它也有可能撕裂一些薄弱内存体系结构,如ARM和Sparc过字边界写入值,看到堆栈溢出对这种事情的更多细节。

边界检查

边界检查是棘手的问题之一,也是正在进行的辩论的主题。 避免边界检查可以提高代码速度,但会带来导致段错误并降低JVM的潜力。 Agrona的缓冲区使您可以选择通过命令行属性agrona.disable.bounds.checks禁用边界检查,但默认情况下是边界检查。 这意味着它们的使用是安全的,但是如果对经过测试的代码进行应用程序性能分析确定范围检查是瓶颈,则可以将其删除。

结论

Agrona的缓冲区使我们可以轻松使用offheap内存,而不受Java现有字节缓冲区强加给我们的限制。 我们正在继续扩展可从maven central下载的库。

感谢Mike Barker,Alex Wilson,Benji Weber,Euan Macgregor和Matthew Cranman对本文的帮助。

翻译自: https://www.javacodegeeks.com/2015/08/agronas-threadsafe-offheap-buffers.html

threadsafe

threadsafe_Agrona的Threadsafe堆缓冲区相关推荐

  1. linux cdc设备驱动程序,Linux Kernel 'cdc-wdm' USB设备驱动程序堆缓冲区溢出漏洞

    发布日期:2013-03-14 更新日期:2013-03-19 受影响系统: Linux kernel 3.x Linux kernel 2.6.x 描述: --------------------- ...

  2. CVE-2021-2429:MySQL InnoDB Memcached 插件中的堆缓冲区溢出漏洞详解

     聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 2021年4月,ZDI 收到了一名匿名者提供的关于MySQL 数据库中某漏洞的报告,结果是位于 InnoDB memcached 插件中的基于堆 ...

  3. php crypt函数缓冲区溢出漏洞,GIMP 堆缓冲区溢出漏洞(CVE-2017-17784)

    GIMP 堆缓冲区溢出漏洞(CVE-2017-17784) 发布日期:2018-04-20 更新日期:2018-05-03 受影响系统:GIMP GIMP 2.8.22 描述: BUGTRAQ  ID ...

  4. 最新系统漏洞--UnRAR堆缓冲区溢出漏洞

    最新系统漏洞2021年12月13日 受影响系统: UnRAR UnRAR 5.6.1.3 UnRAR UnRAR 5.6.1.2 描述: UnRAR是一个可解压rar后缀文件的命令. UnRAR 5. ...

  5. 绿盟科技网络安全威胁周报2017.01 请关注MatrixSSL堆缓冲区溢出漏洞CVE-2016-6890

    绿盟科技发布了本周安全通告,周报编号NSFOCUS-16-39,绿盟科技漏洞库本周新增30条,其中高危9条.本次周报建议大家关注 MatrixSSL 堆缓冲区溢出漏洞 ,目前,此漏洞已经公布了一段时间 ...

  6. radareorg/radare2 堆缓冲区溢出漏洞(CVE-2022-1383)

    编号 CVE-2022-1383 标题 radareorg/radare2 堆缓冲区溢出漏洞 描述 Radare2(简称为r2 )是用于逆向和分析二进制文件的完整框架. GitHub 存储库中 5.6 ...

  7. Agrona的Threadsafe堆外缓冲区

    这篇博客文章解释了我们如何为线程安全操作轻松提供对堆内存的访问,从而继续了我在Agrona库上进行的系列文章 . 在继续进行之前,我可能应该警告一下,这是一个相当高级的主题,并且我不会尝试解释诸如内存 ...

  8. CVE-2021-3156:Sudo 堆缓冲区溢出漏洞(有poc,exp待更新)

    漏洞详情 CVE-2021-3156: 缓冲区溢出漏洞 在sudo解析命令行参数的方式中发现了基于堆的缓冲区溢出.任何本地用户(普通用户和系统用户,sudoer和非sudoers)都可以利用此漏洞,而 ...

  9. java堆缓冲区,Java NIO之Buffer(缓冲区)

    Java NIO主要解决了Java IO的效率问题,解决此问题的思路之一是利用硬件和操作系统直接支持的缓冲区.虚拟内存.磁盘控制器直接读写等优化IO的手段:思路之二是提供新的编程架构使得单个线程可以控 ...

最新文章

  1. TensorFlow基础笔记(11) max_pool2D函数 深度学习
  2. java简单的面试题目_简单的面试题目,大跌眼镜的结果
  3. 手把手教你使用TF服务将TensorFlow模型部署到生产环境
  4. ORACLE SQL SET运算符
  5. visual studio 2019 HTML怎么自动生成代码_敲代码和编程适合什么样的笔记本?深度推荐...
  6. 只不过是R.java文件的特性-----出错信息:R.java was modified manually! Reverting to generated version!...
  7. 心跳脑裂解决方案之Heartbeat的Stonith配置
  8. 谷歌放弃go_盘点国内可以使用的十种谷歌服务
  9. 图像处理之基础---叹为观止的图像处理
  10. python3 parser
  11. CAD二次开发--ZOOM自定义缩放到视口区域,解决SelectCrossingWindow等方法对视口外实体不起作用的问题
  12. linux基础--认识文件以及vi编辑器
  13. java caller_【JavaScript】callee 与 caller
  14. unity如何用代码创建自已的logo
  15. 编程要了解的基础知识
  16. 《满庭芳·国色》色号记录
  17. sql查询记录数大于1
  18. SAP ABAP 解析JSON
  19. Anaconda(miniconda)使用指南
  20. 北京大学计算机考研信息汇总

热门文章

  1. P5405-[CTS2019]氪金手游【树形dp,容斥,数学期望】
  2. YbtOJ#643-机器决斗【贪心,李超树】
  3. [模板]多项式全家桶小记(求逆,开根,ln,exp)
  4. P6015-[CSGRound3]游戏【树状数组】
  5. 2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维)
  6. 【快速幂】小明解密码 (jzoj 2146)
  7. 简单的数学问题 洛谷 P1414 又是毕业季II
  8. csdn颜色字体的改变
  9. 当当网头部和尾部——源码
  10. github创建一个新的tag