Erlang垃圾回收机制

本文介绍了Erlang的垃圾回收机制,包括其"stop the world"的分代标记-清除策略,以及如何通过fullsweep_after参数调整垃圾回收频率。Erlang进程的堆分为年轻代和老年代,垃圾回收以进程为单位进行,对于二进制数据,小于64 bytes存储在进程堆中,大于则单独分配。最后,文章提到了如何控制垃圾回收及调整参数。
摘要由CSDN通过智能技术生成
前面的Erlang杂记中我们简单提到过Erlang的垃圾回收机制:1.以进程为单位进行垃圾回收 2.ETS和原子不参与垃圾回收.今天我们继续这一话题,关注更多关于细节.

   在Erlang的官方文档中,关于垃圾回收的知识散见于各处,要把这些信息收集在一起还是要费些力气的,完全不像微软文档那样系统化,比如这是关于.net framework垃圾回收的文档:http://msdn.microsoft.com/en-us/library/ee787088.aspx ;好吧,有点耐心,还是可以从Erlang官方文档中发现好多宝的,回头再说,现在开始:

 

历史回顾

 简单回顾一下垃圾回收的知识,垃圾回收器的本质实际上是改变存活数据结构构成图的连通性.堆对象在图中的存活性是由指针的可到达性定义的.程序可以操作三种位置的数据:寄存器 程序栈(局部变量 临时变量) 全局变量.这些位置的变量有一部分保存了指向堆数据的引用,他们构成了应用程序的根(Root).对于用户程序动态分配的内存只能通过Root或者根发出的指针链访问,程序不应该访问其地址空间的随机位置.
   内存分配的解决方案有:
    [1] 静态分配 优点是:编译器知道所有的数据位置,实现效率高 缺点是:每一个数据结构的大小必须在编译时可知,方法调用不可以是递归的,因为同一个方法在内存中共享相同的位置. 无法动态创建数据结构
    [2] 栈分配 调用的时候入栈,调用结束出栈;同一个方法的不同调用不再共享地址,递归成为可能;只有大小能在编译时去递归大小的对象池啊能作为过程的结果返回.被调用者的生命周期不可能比调用方的生命周期更长.
    [3]堆分配 闭包成为可能 递归结构的表达式成为可能
 
   垃圾回收的经典算法有:引用计数 标记清除 节点复制
  [1] 引用计数方法是和程序执行同时进行,内存管理的开销比较均匀,这样进行没有长时间的挂起内存管理的时间比较稳定,可以获得比较平滑的响应时间;
  [2]标记清除 内存单元不会被立即回收,而是处于不可到达状态,直到所有的内存都被耗尽,进行全局级别的遍历来确定哪些单元可以回收.显然这种全局级别的中断在实时性要求较高的系统并不实用,甚至视频游戏都不可能接受在GC时有这么长的停顿.如果实时性方面要求不高,标记清除可以获得比引用计数更好的性能.标记清除的代价还是较高,标记是全局级别的,算法复杂度与整个堆大小成正比;标记清除使得内存空间倾向于碎片化.在物理存储器中碎片化的影响不大,但虚拟存储中会导致辅助存储器和主存之间频繁的交换页面,系统出现颠簸.
 [3]节点复制将堆分成两个半区,一个包含现有数据,另一个包含已经被废弃的数据,运行时两个半区的角色不断交换;这样做的优势在于内存分配的开销很小,只需要比较指针,不存在内存碎片的问题.但是内存浪费较大;
 [4]标记-整理缩并  标记所有的存活对象 通过重新调整存活对象位置来缩并对象图;更新指向被移动了位置的对象的指针
 [5] 分代回收 是基于统计学原理的:多数内存块的生存周期都比较短,垃圾收集器应当把更多的精力放在检查和清理新分配的内存块上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值