翻看 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. 手把手教你从购买vps到搭建一个node服务器

    要准备什么? 1.5刀 2.最好有FQ软件(可以用蓝灯) let's Go! 一.vps购买 vps可以选择digital ocean(do) 链接 ,由于是外国网站,响应比较慢,所以最好翻个墙. g ...

  2. 禁用mac Command w

    事情是这样的:历经各种调查,终于定位到了一个bug,正在我准确Command + 数字 切换下iterm2的窗口时,让我懵逼的事情发生了,我们终端不见了,对不见了.心里万马奔腾啊.什么鬼?原来自己误按 ...

  3. 软件工程——sprint 1回顾总结

    主题:“我们在本次sprint中做了什么?接下来的打算?” sprint总结:在本次sprint里,这是我们团队的成员们第一次开始以团队的形式进行一次团队项目开发,早在第一次团队会议之时,我们便因团队 ...

  4. HTTP请求响应报文&&相关状态码&&GET_POST请求方法 总结

    HTTP请求报文: 一个HTTP请求报文由四个部分组成:请求行.请求头部.空行.请求数据 1.请求行   请求行由请求方法字段.URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔.比如 GE ...

  5. JS Date.Format

    // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...

  6. ASP.NET MVC的路由

    好久没写博文了,感觉最近好像少了点动力.唉!这回就看看这个MVC的路由. 说这个路由机制其实不是MVC里面特有的,ASP.NET里面本身就有的,只不过在WebForm里面一般比较少用,而在MVC里就是 ...

  7. Android读写SD卡

    SD卡的读写是我们在开发Android 应用程序过程中最常见的操作.下面介绍SD卡的读写操作方式: 1. 获取SD卡的根目录 String sdCardRoot = Environment.getEx ...

  8. 重新想象 Windows 8.1 Store Apps (80) - 控件增强: WebView 之基本应用, POST 数据, 与 JavaScript 交互

    [源码下载] 重新想象 Windows 8.1 Store Apps (80) - 控件增强: WebView 之基本应用, POST 数据, 与 JavaScript 交互 作者:webabcd 介 ...

  9. [PHP] PHP请求Socket接口测试

    使用php读取socket接口的数据,通过php传递请求方法和请求参数,得到返回结果 PHP文件: <?php class Test{ const IP='127.0.0.1'; const p ...

  10. IE Unknown runtime error

    1. 在函数中使用原生的js的时候,有时在IE下会出现Unknown runtime error 火狐下正常 2. 解决办法, 将原生js改成jquery处理兼容问题 document.getElem ...