现代VM如何处理内存分配?
我正在研究用C编写的简单堆栈机器,主要用于学习目的。 在使用malloc/free
进行内存操作之后,我认为从现代虚拟机中读取一些特定于内存分配的代码是个好主意。
我下载了Lua源代码并开始阅读它。 过了一会儿,我意识到涉及很多宏的东西,我找不到真正的内存分配完成的代码(即malloc
调用)。
find . -exec grep -i "malloc" '{}' \; -print
它只打印了一些名称中包含malloc
单词的Lua宏。 Lua VM(和编程语言)根本不使用malloc
!
所以这引出了一个问题:现代VM如何处理内存分配? Lua如何从堆中分配内存? 除了malloc
之外,还有什么方法可以进行分配吗? 其他方法的优缺点是什么?
我也想知道安全地处理分配的内存的最佳实践,设计模式等。 我在Lua的源代码中看到,在分配内存之前有很多间接。 我在哪里可以了解这些东西?
Lua绝对使用malloc
,以realloc
的forms(也可以通过自定义分配器),但是,因为Lua使用GC类似99%的基于VM的语言,它使用宏自动将GC头块添加到分配。
您会发现Lua的内存全部由lmem.c
和lmem.h
的LuaM_
例程处理,这些都使用VM的全局状态来存储分配器,该分配器最初设置为l_alloc
(来自lauxlib.c
),但是由lua_setallocf
改变。
最近,LuaJIT增加了分配下沉和计划一些非常酷的内存function,你可以在LuaJIT垃圾收集上阅读这篇文章。 本文介绍了围绕VM / JIT内存分配,下沉,聚合和垃圾收集的许多策略和设计。
正如您所看到的,内存分配和下沉策略与使用的GC(如果有)密切相关。
就各种内存分配器的pro和con而言,使用标准malloc
很容易使用,但代价是速度和浪费对齐以及标记到每个分配的各种额外块。
转向更高级的竞技场,池,平板和块分配器,我们可以大大加快速度(特别是对于固定大小的内部VM分配),并避免使用更通用的分配器(如malloc
可能发生的大量碎片和开销,但是当然这些分配器更复杂,如果你从头开始(在像VM这样的大型系统只是要求问题的话),你必须调试它们,就像经过试验和测试的CRT malloc
实现一样。
Lua核心不使用malloc
和朋友。 它依赖于用户提供的内存分配函数,该函数具有类似realloc
的语义(但在处理NULL
指针和大小为0时更精确)。 见lua_Alloc 。
辅助Lua库提供了一个方便的luaL_newstate
函数,它通过核心lua_newstate
函数使用基于标准realloc
和free
的内存分配函数创建一个Lua状态。 其他客户端可以使用适合其应用程序的任何内存分配。