翻看 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. Python内置模块(2)

    这一部分主要介绍sys.os.hashlib和re模块.其中的re模块介绍得非常详细,是本部分的重点! 均为python3.5.1环境. 一.sys模块 sys模块涉及的主要是与python解释器相关 ...

  2. IOS开发UI基础UITextFidle相关属性

    UITextFidle相关属性 •    enablesReturnKeyAutomatically默认为No,如果设置为Yes,文本框中没有输入任何字符的话,右下角的返回按钮是disabled的. ...

  3. 一、HTTPServer,RequestHandler,ServerHandler,Handler

    1.      HTTPServer,RequestHandler,ServerHandler,Handler 1.1       基本概念 HTTPServer主要是对传输控制层HTTP,TCP,S ...

  4. Mantis 缺陷管理系统配置与安装

    什么是Mantis MantisBT is a free popular web-based bugtracking system (feature list). It is written in t ...

  5. SQL索引学习-索引结构

    前一阵无意中和同事讨论过一个SQL相关的题(通过一个小问题来学习SQL关联查询),很惭愧一个非常简单的问题由于种种原因居然没有回答正确,数据库知识方面我算不上技术好,谈起SQL知识的学习我得益于200 ...

  6. 与众不同 windows phone (46) - 8.0 通信: Socket, 其它

    [源码下载] 与众不同 windows phone (46) - 8.0 通信: Socket, 其它 作者:webabcd 介绍与众不同 windows phone 8.0 之 通信 Socket ...

  7. 不经意间网易开源镜像去掉了FreeBSD的镜像

    http://mirrors.163.com/ FreeBSD已经到了这么不招人待见的地步了么? 网易曾经可是FreeBSD的大户啊.

  8. android 学习资料

    Fragment 事件分发机制 事件分发机制2 NDK JNI ndk { moduleName "mymodule" ldLibs "log" stl &qu ...

  9. 六个创建模式之工厂方法模式(Factory Method Pattern)

    问题: 在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则. 定义: 定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类.此时工厂和产品都具有相同的继承结构,抽象产 ...

  10. 【GOF23设计模式】建造者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]建造者模式详解类图关系 建造飞船 package com.test.Builder; public class AirShi ...