延迟释放内存
问题:
怎样在多线程时中进行内存的管理呢?有个简单的方法:内存分配器给所有的线程分配和销毁内存的时候都被一个全局锁保护,但这会造成锁争,效率底下。那么给每个调度器单独的一个内存分配器实例呢,这样就避免了锁争,但是有这样一种情况,本线程创建的内存,有可能被其他线程正在使用,那么当内存需要销毁的时候怎么办呢。难道要等原线程的内存分配器不处在被锁状态才能释放?这样你等我,我等他的还是效率底下啊。
解决方案:
为了减少由内存分配器引起的锁争,我们给每个调度器进程一个无锁状态的内存分配器,给非调度器的进程一个有锁的内存分配器。调度器在erlang虚拟机beam中是做主要工作的(所有的erlang进程的运行都是调度器来做的,erlang进程只是一个虚拟的概念),所以这样能避免大部分的锁争。
既然我们仍然需要一种方法在线程之间共享内存,我们就要管理他们。只有创建一个内存的内存分配器所属的线程才有资格释放这个内存。当其他调度器进程需要释放某个由其他调度器所属分配器实例创建的内存的时候,他把需要被释放的内存概括成一个“释放任务”通知给创建这个内存的内存分配器所属的线程,每个调度器线程都有一个类似“收件箱”的东西来接收这类“释放任务”,当调度器线程探测到了这类“释放任务”后,他会真正的释放这个内存。
“收件箱”是由一个单链表实现的。链表节点的顺序无所谓。插入新节点在链表的尾部附近,而直接在尾端插入新节点容易在多线程同事插入大量节点时导致不必要的数据竞争。
为什么呢?
正常情况下,我们始终有个指针(尾指针)是指向链表的尾部的,但在多线程同时访问链表的时候我们就不能这么做了,而是把尾指针指向尾部附近的某个节点,位置不是固定的,只要在尾部附近就行。
正常情况下,我们往链表插入数据,我们就把原来尾部节点的指针由null改成指向新节点,然后链表的尾指针也指向这个新节点。
但是当有大量的线程来执行上面说的操作的话,有可能1线程刚刚把尾部的节点E的指针指向新创建的节点E1,2线程就把E的指针指向E2,结果导致了1线程刚刚的操作完全失败了,E1节点被弄丢了。为了避免这种情况,每次有线程需要插入节点时都是在单链表尾部节点的附近插入节点,这样只要同一时间不同的线程锁插入的节点位置不是同一个节点后的话,就不会产生数据竞争,从而避免了错误,又提高了效率。
对于某个调度器线程来说,自己的“收件箱”是怎么来维护的呢?首先他有两个指针指向这个收件箱,第一个指针是指向单链表头的(head.first),还有一个是指向单链表尾的(head.unref_end),每当这两个指针不一致的时候,调度器线程就知道应该执行内存的释放任务了。
因为单链表是不断更新的,不断会有其他的线程向这个单链表的尾部附近插入“释放任务”,所以调度器线程会定期的移动head.unref_end去单链表的最尾端。
以上就是延迟释放的大概需要了解的地方。源代码我没,有什么问题欢迎大家指正。
相关推荐
Erlang Runtime System Application, ERTS, contains functionality necessary to run the Erlang system. Note: By default, ERTS is only guaranteed to be compatible with other Erlang/OTP components from the...
erlang opt system document
kernel - code necessary to run the Erlang runtime system itself; sasl - the system architecture support libraries application; stdlib - modules for manipulating lists, strings, files etc.
erlang otp 19.1 官网文档 HTML格式 官网的下载是真的糟糕。
远古封神Server(erlang源码)+文档+mongodb数据库 远古封神Server(erlang源码)+文档+mongodb数据库
erlang api Erlang Run-Time System Application The Erlang Runtime System Application ERTS.
Erlang OTP 设计原理文档 概述: 在Erlang/OTP中有一个基本概念叫监督树。这是一种建立在督程与佣程思想上的进程结构化模型。
vim-erlang-runtime, Vim的Erlang缩进和语法 用于Vim的Erlang缩进和语法这是 Vim ( 来自 Vim 7.4 ) 附带的Erlang缩进和语法。安装方法 1克隆这里存储库: $ mkdir -p ~/.vim/bundle $ cd ~/.vim/b
erlang 中文,chm参考文档
erlang介绍介绍opt开发方法中文资料
Vim 的 Erlang 运行时文件 ... ~ /.vim/pack/foo/start/vim-erlang-runtime 重新启动 Vim。 病原关于病原体的信息:。 安装步骤: 克隆这个存储库: $ git clone https://github.com/vim-erlan
erlang中文手册(R11B 文档译文,最适合入门) erlang位运算与二进制解析 erlang二进制高效编程 erlang异常处理详解 开发经验: 面对软件错误构建可靠的分布式系统 编写分布式的 Erlang 程序:陷阱和对策 硝烟中的...
Erlang是一个由Ericsson计算机科学试验室设计开发的程序语言。开源的Erlang已经发布以帮助、鼓励在爱立信以外来发展这门语言。
Centos7安装RabbitMQ的文档和安装包,包含erlang的安装文档和安装包。RabbitMQ版本是3.7.12。
经过本人亲自在多台机子上测试。 表示 该文档可以信任。 本文当是基于Eclipse的。
erlang-runtime_tools-19.3.6.4-1.el7.x86_64.rpm
Erlang的单元测试文档,eunit.
erlang入门电子书 erlang编程 Introducing Erlang,作者Simon.St.Laurent
Erlang是一个结构化,动态类型编程语言,内建并行计算支持。最初是由爱立信专门为通信应用设计的,比如控制交换机或者变换协议等,因此非常适 合于构建分布式,实时软并行计算系统。 使用Erlang编写出的应用运行时...
学习erlang 开发游戏利器 erlang学习文档 erlang学习工具