`
cwqcwk1
  • 浏览: 86923 次
文章分类
社区版块
存档分类
最新评论

erlang二进制数据垃圾回收机制

 
阅读更多

erlang二进制数据在内存中有两种存在形式,当数据大小不到 64 bytes,就直接存在进程堆内,如果超过了64 bytes,就被保存到进程外的共享堆里,可以给节点内所有进程共享。

erlang有两种二进制容器:heap binaries和refc binaries。

heap binaries

Heap binaries are small binaries, up to 64 bytes, that are stored directly on the process heap. They will be copied when the process is garbage collected and when they are sent as a message. They don't require any special handling by the garbage collector.

这个就是进程堆二进制,是一些比较小的二进制数据,每个数据大小不超过64bytes,这些数据保存在进程堆内。对于这里的二进制数据,垃圾回收走的是进程堆数据的回收机制,参考这里。如果发给其他进程的消息含有这些数据,erlang将直接复制一份到别的进程堆内。

针对heap binaries,在R13B03后,erlang还增加了bin vheap来加快二进制数据的回收。

OTP-8202 A new garbage collecting strategy for binaries which is more aggressive than the previous implementation. Binaries now has a virtual binary heap tied to each process. When binaries are created or received to a process it will check if the heap limit has been reached and if a reclaim should be done. This imitates the behavior of ordinary Erlang terms. The virtual heaps are grown and shrunk like ordinary heaps. This will lessen the memory footprint of binaries in a system.

就是说heap binaries的垃圾回收使用了进程堆数据的回收方式,但使用了一个虚拟二进制堆(vheap)来计算这些二进制的使用情况,加快内存回收速度。

refc binaries

Refc binaries consist of two parts: an object stored on the process heap, called a ProcBin, and the binary object itself stored outside all process heaps.The binary object can be referenced by any number of ProcBins from any number of processes; the object contains a reference counter to keep track of the number of references, so that it can be removed when the last reference disappears.

官方的叫法是引用计数二进制,就是对于那些超过64bytes的二进制数据,他们如果直接保存在进程堆内,将导致进程频繁的gc,比较大的数据复制来复制去开销也很大。所以,erlang将这些数据保存在进程外的共享堆,再把这个二进制数据的地址给拥有这个数据的进程。所以,进程堆内保存的是这个二进制数据的引用,叫ProcBin。如果进程把这个二进制数据发给其他进程,erlang也不再复制整个二进制数据,而是直接再生成一份ProcBin到别的进程堆内。那么,这个二进制数据就可以多个进程的ProcBin引用,当没有一个ProcBin引用到这个二进制数据,这个二进制就被erlang回收。

所以,这种二进制数据的gc的是引用计数的回收机制。注意了,ProcBin是进程堆内数据,走的是进程堆数据的回收方式。

什么是引用计数垃圾回收机制

引用计数就是每个数据对象都配有一个计数器,计算对象被引用的次数。多了一个引用就加1,少一个引用就减1,当引用次数为0时就回收数据。这种垃圾回收机制实现简单,回收及时,但也有副作用,就是容易造成循环引用,就是A引用B,B引用C,C引用了A,导致A、B、C都无法被回收。

那么,erlang会不会也有循环引用的问题?这里就不用担心,erlang的变量是单向赋值,只存在ProcBin对二进制对象的单向引用

最后,说下erlang另外两种二进制数据:sub binary和match context

A sub binary is created by split_binary/2 and when a binary is matched out in a binary pattern. A sub binary is a reference into a part of another binary (refc or heap binary, never into a another sub binary). Therefore, matching out a binary is relatively cheap because the actual binary data is never copied.

A match context is similar to a sub binary, but is optimized for binary matching; for instance, it contains a direct pointer to the binary data. For each field that is matched out of a binary, the position in the match context will be incremented.

前面谈到erlang为避免二进制数据复制带来的时间和空间的开销,erlang这里做得更彻底一点,sub binary和match context其实是引用对象,被用来引用heap binary和refc binary的数据

说到sub binary和match context,这两者有什么区别?

sub binary是一个子二进制数据,从一个二进制分割出来,或匹配一个二进制后产生,具有二进制数据通用的属性和方法;match context是匹配上下文,在erlang进行二进制数据匹配时产生,如果接下来使用了匹配到的二进制数据,那么erlang就将这个match context数据转成sub binary,就是说,match context数据不直接被用户使用,只是erlang用以二进制匹配优化的过程数据

erlang二进制gc的副作用

从上面的内容可以知道,erlang二进制gc有两种gc,heap binary的是进程堆的分代gc,refc binary的是分代gc+引用计数。所以在上文讲到的erlang垃圾回收的副作用,这里同样会有。而且,erlang二进制还加入了引用对象的概念,一个二进制数据可以有多个引用,可以被多个进程引用,也就是要多个进程堆的分代gc后才能回收,这就使得二进制gc更难控制,回收不及时。

另外,在实际的网络开发中,我们需要的数据可能只是二进制数据的一小部分,从上面的内容也可以了解到,如果我们还在使用二进制数据的一部分,那这个二进制数据是不会参与gc的。针对这个问题我们该如何解决?

%% 生成一个100字节的二进制A
1> A = binary:copy(<<1>>,100).
<<1,1,1,1,1 ...
2> byte_size(A).
100
3> binary:referenced_byte_size(A).
100

%% 匹配二进制,产生子二进制B
4> <<_:10/binary,B:10/binary,_/binary>> = A.
<<1,1,1,1,1 ...
5> byte_size(B).
10
6> binary:referenced_byte_size(B).
100

%% 复制二进制生成二进制C
7> C = binary:copy(B).
<<1,1,1,1,1,1,1,1,1,1>>
8> binary:referenced_byte_size(C).
10
上面,二进制B是二进制A的子二进制,如果B还有使用,A就不会参与gc;而二进制C是一个新的二进制,不会引用二进制A,让A可以参与垃圾回收

更新说明:

2014/06/13 补充了 erlang二进制垃圾回收的副作用


参考:

http://blog.csdn.net/mycwq/article/details/26741387
http://www.erlang.org/doc/efficiency_guide/binaryhandling.html#id65798

分享到:
评论

相关推荐

    erlang rebar 二进制

    erlang rebar 二进制

    erlang二进制共享对象的存储方式

    ### Erlang二进制共享对象的存储方式 #### 引言 随着计算机技术的发展与进步,数据处理的速度和效率成为了衡量系统性能的关键因素之一。在众多优化策略中,缓存技术因其能显著提升数据访问速度而备受关注。本文将...

    PHP扩展模块解包Erlang term二进制数据

    有些同学想把Erlang数据通过term_to_binary函数封包后以二制进形式存入数据库,然后用PHP读取并解包成PHP数组。 为了解决上面的这种应用场合中遇到的问题, 参考peb(Php-Erlang Bridge)扩展写了这个类似erlang:...

    binpp::1234:Erlang二进制漂亮打印机

    **binpp:Erlang二进制漂亮打印工具** `binpp`,全称为"Binary Pretty Printer",是一个Erlang库,其主要功能是将复杂的二进制数据结构以人类可读的格式进行输出,方便开发者调试和理解。"1234"可能是指版本号或者...

    FsServer:Julia 的基于 TCP 的 Erlang 二进制术语服务器

    2. **Erlang 二进制协议支持**:FsServer 能够理解和处理 Erlang 的二进制术语,允许用户发送和接收符合该协议的数据结构,如列表、映射、原子等,增强了跨语言交互的能力。 3. **文件操作**:FsServer 提供了丰富...

    erlang文献及资料汇总

    erlang二进制高效编程 erlang异常处理详解 开发经验: 面对软件错误构建可靠的分布式系统 编写分布式的 Erlang 程序:陷阱和对策 硝烟中的Erlang 深入底层: erlang VM基于多核处理器的可伸缩性特征 erlang VM内部...

    php实现与erlang的二进制通讯实例解析

    - **Erlang的位语法**:Erlang中的位语法允许开发者直接通过位模式来匹配二进制数据。这为处理二进制通讯提供了极大的便利,使得可以非常灵活地读取和构造二进制数据。 了解了上述知识点后,我们可以总结出php与...

    bstr:Erlang库将二进制文件用作字符串

    Erlang库将二进制文件用作字符串。 要求 在以下OTP版本中进行了测试: 17.1 17.0 R16B03-1 R16B03 R16B02 R16B01 安装 要初始化项目,请运行make bootstrap 。 要编译模块,您只需运行make 。 要运行单元...

    球拍位语法:球拍的Erlang样式二进制位串

    在编程领域,尤其是在处理底层数据或通信协议时,二进制位串的处理是一项重要的技能。Erlang语言以其高效处理并发和大量I/O操作而闻名,它提供了一种独特的语法来操作二进制位串,称为“球拍位语法”(Bit Syntax)...

    erlang语言实现binary_to_term完整代码

    erlang提供了binary_to_term 函数...这个函数都是c实现的,这里用erlang语言实现了,很有参考价值,其他语言可以参考这个解析erlang二进制协议数据。配套文章地址http://blog.csdn.net/mycwq/article/details/42460033

    erlmc:Erlang Memcached二进制协议客户端

    Erlang二进制协议Memcached客户端 外部文件 二进制协议规范 快速开始 您必须具有1.3或更高版本的memcached $&gt; make $&gt; make test $&gt; sudo make install $&gt; memcached -d 1&gt; erlmc:start(). ok 2&gt; erlmc:stats(). ...

    介绍 Erlang binary 和 bit string 数据类型的经典文章

    自 R12B 版本以来,Erlang 在处理二进制数据方面引入了两项重大更新:bit strings(位字符串)以及 binary comprehensions(二进制推导)。这些新特性不仅增强了Erlang处理二进制数据的能力,而且使得开发者能够更加...

    binary_tools:一些有用的二进制函数

    binary_tools是Erlang二进制数据类型的一组辅助服务函数。 目录树 $ tree . ├── README.md ├── c_src │ └── binary_tools.c ├── ebin ├── example │ └── get_bin_address_ex.erl ├── ...

    erlang_版本24.3.4.4

    5. **安装**:最后,使用`make install`将编译好的Erlang二进制文件安装到你的系统路径。在某些系统上,你可能需要管理员权限执行此操作。 Erlang的主要特性包括: - **并发性**:Erlang的进程模型是轻量级的,...

    Erlang Windows 64位 安装包

    "Erlang Windows 64位 安装包"指的是针对Windows操作系统64位架构的Erlang二进制安装程序。这个特定的版本是v22.0,名为"esl-erlang_22.0_windows_amd64.exe",由Erlang Solutions Limited(ESL)提供。ESL是一家...

    ohmyguard:erlang 函数保护的二进制模式匹配样式语法

    Erlang 二进制模式匹配是它最好的特性之一,也是它最简洁的语法,那么为什么不将它也应用于函数保护呢? 鉴于此功能: my_func ( Value ) when is_binary ( Value ) -&gt; Value . 可以简化为: my_func ( Value / ...

    erlang 21.3

    5. **安装**: 最后,用`sudo make install`将编译好的Erlang二进制文件安装到系统路径中。 在实际应用中,Erlang 21.3可能会带来以下一些关键变化或改进: - **性能提升**: 每个版本的Erlang都会在性能方面进行...

    Erlang6大数据存储方式总结

    虽然MySQL不是Erlang原生的存储解决方案,但其强大的SQL查询能力和成熟的社区支持使其在处理复杂查询和大规模数据时表现出色。通过Erlang与MySQL的集成,开发者可以利用两者的优点,构建混合型的存储解决方案。 ...

    erlang port driver test

    2. **数据传输**:Erlang 进程通过端口发送二进制数据到外部程序,外部程序处理后返回结果,数据通过端口返回到 Erlang 进程。Erlang 使用 `port_command/2` 发送数据,`port_recv/2` 接收数据。 3. **同步通信**:...

Global site tag (gtag.js) - Google Analytics