本篇文章,主要探讨一下lua中的内存管理(涉及到的文件 lmem.c,lauxlib.c )。

lua内存管理:

众所周知,lua是用纯c写的,所以lua中的内存管理,也就是用c方式对内存的管理。

/*

** 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!)

*/

注释中写的比较清楚,使用 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 = …,通过当前栈指针L获得全局栈指针g,栈指针,以及全局栈指针,将在后续的文章中说明;

block = (*g->frealloc)(),通过frealloc接口释放block指针指向大小为osize的内存,申请nsize大小的内存,且用block指针指向,这里把要释放的内存和新申请的内存共享一个指针;

g->totalbytes = …, 刷新全局内存计数;

return block, 返回指向新申请的内存的指针;

内存管理的其他宏定义,如:luaM_reallocv,luaM_freemem,luaM_free,luaM_malloc,luaM_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指向的内存,反之,则realloc一下ptr指向的内存,free,realloc都是c提供的内存操作API。