lua内存管理

2015年03月23日 16:51 0 点赞 0 评论 更新于 2025-11-21 18:20

本篇文章主要探讨 Lua 中的内存管理,涉及到的文件有 lmem.clauxlib.c

Lua 内存管理概述

众所周知,Lua 是用纯 C 语言编写的,因此 Lua 中的内存管理本质上是采用 C 语言的方式来进行的。

关于 frealloc 函数

/*
** About the realloc function:
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** (`osize’ is the old size, `nsize’ is the new size)
**
** Lua ensures that (ptr == NULL) iff (osize == 0).
**
** * frealloc(ud, NULL, 0, x) creates a new block of size `x’
**
** * frealloc(ud, p, x, 0) frees the block `p’
** (in this specific case, frealloc must return NULL).
** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ANSI C)
**
** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/

从注释中可以清晰地了解到,Lua 使用 void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 接口来进行内存的释放和分配操作。该接口将内存的释放和分配操作整合在同一个函数中,既可以只进行释放操作,也可以只进行分配操作,还可以同时进行释放和分配操作。

源码分析

/*
** generic allocation routine.
*/
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
global_State *g = G(L);
block = (*g->frealloc)(g->ud, block, osize, nsize);
g->totalbytes = (g->totalbytes - osize) + nsize;
return block;
}

为了便于代码分析,我们去掉源码中的断言。具体分析如下:

  • global_State *g = G(L);:通过当前栈指针 L 获得全局栈指针 g。栈指针以及全局栈指针的详细说明将在后续文章中展开。
  • block = (*g->frealloc)(g->ud, block, osize, nsize);:通过 frealloc 接口释放 block 指针指向的大小为 osize 的内存,并申请大小为 nsize 的内存,最后让 block 指针指向新申请的内存。这里将需要释放的内存和新申请的内存使用同一个指针来管理。
  • g->totalbytes = (g->totalbytes - osize) + nsize;:刷新全局内存计数,确保对 Lua 中使用的总内存量进行准确记录。
  • return block;:返回指向新申请内存的指针。

此外,内存管理的其他宏定义,如 luaM_reallocvluaM_freememluaM_freeluaM_mallocluaM_new 等,实际上只是对 luaM_realloc_ 接口进行了再次封装,理解起来相对容易。

frealloc 的实现细节

在前面的分析中,我们只知道使用 frealloc 接口来进行内存的释放和分配操作,下面我们来深入了解它的具体实现。

static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void)ud;
(void)osize;
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}

这段代码非常简洁明了。当 nsize 等于 0 时,表示只需要释放 ptr 指向的内存,此时调用 C 标准库中的 free 函数进行释放操作,并返回 NULL。反之,如果 nsize 不为 0,则调用 realloc 函数对 ptr 指向的内存进行重新分配。freerealloc 都是 C 语言标准库提供的内存操作 API。

作者信息

menghao

menghao

共发布了 3994 篇文章