翻看 BEAM 虚拟机指令集的时候(在编译器源码目录下:lib/compiler/src/genop.tab),会发现有一些和内存分配/解除分配相关的指令,如下所示:

  • allocate StackNeed Live
  • allocate_heap StackNeed HeapNeed Live
  • allocate_zero StackNeed Live
  • allocate_heap_zero StackNeed HeapNeed Live
  • test_heap HeapNeed Live
  • init N
  • deallocate N

上述列表中粗体是指令本身,后面跟着的是参数。粗看上去又是 allocate 又是 heap,好像 beam 在虚拟机指令就要处理内存管理。其实不是的。仔细看一下,每一条带 allocate 的指令后面都有一个 StackNeed 参数,原来 BEAM 虚拟机中所谓的内存分配都跟栈有关。我们先看一下Erlang进程里面堆和栈的关系:

堆和栈其实都在统一管理的堆里面,堆从低地址开始向上增长,栈从高地址开始向下增长。栈顶和堆顶碰到了就说明堆的空间不够用了。堆用于保存 Erlang 对象。和 C 语言一样,BEAM 的函数调用也会在栈里面设置栈帧,其中包括函数返回地址以及函数在求值过程中使用的临时数据。栈里面保存的只能是 Eterm,即要么是简单对象,要么是引用对象。对立面保存的是 Eterm 或对象本身。

下面以 allocate StackNeed Live 为例阐述。这条指令说明要在栈上分配 StackNeed 字的空间。那么这条指令后面的 Live 是什么意思呢?在 http://erlangonxen.org/more/beam#model 有一句解释

'Live' refers to the current number of registers that hold values still needed by the process.

表示当前进程所需的寄存器数?看了下面这个图就明白了:

除了堆栈之外,还有寄存器区域。堆栈是进程私有的数据结构,而寄存器组则是虚拟机(调度器)里面的共享数据。当虚拟机调度运行某个进程的时候,这个进程具有对寄存器组的完全访问权。但是当进程被调出的时候,寄存器组就归别人使用了(和 x86 机器不同,保存进程上下文的时候不保存寄存器信息,所以 Erlang 进程切换效率很高)。

上面的 Live 就是图中显示的 live 区域,也就是说,当前这个进程正在使用 live 个寄存器。那为什么分配栈内存的时候需要传入 live 参数呢?而且为什么前面几条分配指令都需要 live 参数呢?这是因为前面几条指令涉及到栈分配(前4条)和堆检查,这些操作都有可能会涉及到垃圾回收(假设分配了栈内存之后栈顶会碰到堆顶),而 Erlang 的垃圾回收需要扫描引用树,所以需要一个扫描的起点,即 rootset。那么根据上面图中对象之间的引用关系,栈中所有的项式和 live 个寄存器的项式都需要加入到 rootset 中。这就是这些和栈分配相关的指令都需要 live 参数的原因。

有了以上基础之后就好理解这些指令了。这些指令的意义总结如下:

  • allocate StackNeed Live:将栈底指针向下挪 StackNeed+1 个字,多出的那个字保存CP(continuation pointer,即函数的返回地址)
  • allocate_heap StackNeed HeapNeed Live:向栈底指针向下挪 StackNeed+1 个字(+1原因同上),还要保证堆中剩余 HeapNeed 个字的空闲空间
  • allocate_zero StackNeed Live:同 allocate,但是新分配的栈空间填零(NIL)
  • allocate_heap_zero StackNeed HeapNeed Live:allocate_heap和allocate_zero的合体
  • test_heap HeapNeed Live:检查对空闲空间是否有 HeapNeed 个字,如不满足要垃圾回收。以上指令都有可能垃圾回收
  • init N:栈中第 N 个字清零(NIL)
  • deallocate N:将栈底指针向上挪 N+1 个字(释放栈)

Erlang 虚拟机 BEAM 指令集之内存管理相关的指令的更多相关文章

  1. 学习android内核 -- 内存管理相关

    Android内存管理: 1.当应用程序关闭以后,后台对应的进程并没有真正的退出(处于休眠状态,一般不占用系统CPU的资源),这是为了下次再启动的时候能快速启动. 2.当系统内存不够时,AmS会主动根 ...

  2. node 内存管理相关

    为什么在node中要担心node内存管理 使用JavaScript进行前端开发时几乎完全不需要关心内存管理问题,对于前端编程来说,V8限制的内存几乎不会出现用完的情况,v8在node中有着内存的限制( ...

  3. C内存管理相关内容--取自高质量C++&C编程指南

    1.内存分配方式 内存分配方式有三种: (1)从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2) 在栈上创建.在执行函数 ...

  4. heap corruption detected错误解决方法调试方法以及内存管理相关

    1.heap corruption detected http://vopit.blog.51cto.com/2400931/645980   heap corruption detected:aft ...

  5. davlik虚拟机内存管理之一——内存分配

    转载自http://www.miui.com/thread-74715-1-1.html dalvik虚拟机是Google在Android平台上的Java虚拟机的实现,内存管理是dalvik虚拟机中的 ...

  6. xcode 手动管理内存 的相关知识点总结

    一.XCode4.2以后支持自动释放内存ARC xcode自4.2以后就支持自动释放内存了,但有时我们还是想手动管理内存,这如何处理呢. 很简单,想要取消自动释放,只要在  Build Setting ...

  7. JVM内存管理------JAVA语言的内存管理概述

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  8. JVM内存管理之JAVA语言的内存管理概述

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  9. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...

随机推荐

  1. iOS-设计模式-懒加载

    一.为什么要懒加载? 答: iPhone设备内存有限,如果在程序在启动后就一次性加载将来会用到的所有资源,那么久可能会耗尽iOS设备的内存.这些资源例如大量的数据,图片,音频,过多的控件等. 二.懒加 ...

  2. 基于openssl的单向和双向认证

    1.前言 最近工作涉及到https,需要修改nginx的openssl模块,引入keyless方案.关于keyless可以参考CloudFlare的官方博客: https://blog.cloudfl ...

  3. .Net魔法堂:log4net详解

    一.作用 提供一个记录日志的框架,可以将日志信息记录到文件.控制台.Windows事件日志和数据库(MSSQL.Acess.Oracle.DB2和SQLite等). 二.先看看示例,感受一下吧   c ...

  4. http与websocket(基于SignalR)两种协议下的跨域基于ASP.NET MVC--竹子整理

    这段时间,项目涉及到移动端,这就不可避免的涉及到了跨域的问题.这是本人第一次接触跨域,有些地方的配置是有点麻烦,导致一开始的不顺. 至于websocket具体是什么意义,用途如何:请百度. 简单说就是 ...

  5. 【Beta阶段】团队源代码管理

    0. 快速上手与理解 如果你的团队来了一个新队员,有一台全新的机器,你们是否有一个文档,只要设置了相应的权限,她就可以根据文档,从头开始搭建环境,并成功地把最新.最稳定版本的软件编译出来,并运行必要的 ...

  6. scrum1.4---Sprint 计划

    燃尽图

  7. 【CODEVS 3287】【NOIP2013】火车运输

    http://codevs.cn/problem/3287/ 题目描述 国有 座城市,编号从 到 ,城市之间有 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 辆货车在运输货物, 司机们想 ...

  8. [moka同学笔记]YII2中发送邮件示例(转载)

    原文:http://yiilib.com/topic/675/Yii2%E4%B8%AD%E5%8F%91%E9%80%81%E9%82%AE%E4%BB%B6%E7%A4%BA%E4%BE%8B { ...

  9. js小数计算小数点后显示多位小数(转)

    首先写一个demo 重现问题,我使用的是一个js在线测试环境[打开] 改写displaynum()函数 function displaynum(){var num = 22.77;alert(num ...

  10. tomcat filewatchdog but has failed to stop it原因以及解决方法

    停止tomcat,有些时候会报The web application [/XXX] appears to have started a thread named [FileWatchdog] but ...