Lua4.0 内存分配

先来看一下 lua 的内存分配。

内存分配的文件是 lmem.h 及对就的 lmem.c。

内存分配方法为 luaM_realloc 和 luaM_growaux。

其它的内存操作接口是定义的宏,通过调用上面的两个基本方法实现。

看一下实现:

/*
** generic allocation routine.
*/
void *luaM_realloc (lua_State *L, void *block, lint32 size) {
  if (size == 0) {
    free(block);  /* block may be NULL; that is OK for free */
    return NULL;
  }
  else if (size >= MAX_SIZET)
    lua_error(L, "memory allocation error: block too big");
  block = realloc(block, size);
  if (block == NULL) {
    if (L)
      luaD_breakrun(L, LUA_ERRMEM);  /* break run without error message */
    else return NULL;  /* error before creating state! */
  }
  return block;
}

核心是调用  realloc 那一句来分配内存。

其它的是一些边界处理。

size 为 0 时则释放 block 内存。(realloc 第二个参数为 0 时也可以释放内存。)

一次最大不可申请超过 MAX_SIZET 的内存。

void *luaM_growaux (lua_State *L, void *block, size_t nelems,
               int inc, size_t size, const char *errormsg, size_t limit) {
  size_t newn = nelems+inc;
  if (nelems >= limit-inc) lua_error(L, errormsg);
  if ((newn ^ nelems) <= nelems ||  /* still the same power-of-2 limit? */
       (nelems > 0 && newn < MINPOWER2))  /* or block already is MINPOWER2? */
      return block;  /* do not need to reallocate */
  else  /* it crossed a power-of-2 boundary; grow to next power */
    return luaM_realloc(L, block, luaO_power2(newn)*size);
}

用来为数组动态增长时分配内存。

申请内存时以 2 的整数次幂边界对齐。因为有这个限制,在某些情况是不需要分配内存的。比如,nelems 为 10, inc 为 5, 就不需要分配内存,因为原来的为 10 分配内存的时候已经分配为 16 了(大于 10 的最小的 2 的整数次幂的数。)。翻译成业务语言就是,如果数组的元素个数由 10 个增长到 15 个,程序并不会进行内存分配。因为元素为 10 个的数组的内存分配量实际上是 16 个元素。

luaO_power2 的实现如下所示:

/*
** returns smaller power of 2 larger than `n' (minimum is MINPOWER2)
*/
lint32 luaO_power2 (lint32 n) {
  lint32 p = MINPOWER2;
  while (p<=n) p<<=1;
  return p;
}


最后也是调用 luaM_realloc 来完成内存的分配。


顺便看一下那几个用来 DEBUG 的内存分配接口。

调试用的内存分配时,每个分配的内存块后面加了一个标记用的块。

如果程序运行中发现标记块内容不对了,一定是有程序写越界了。

方便程序员查找出问题所在。


在其它程序里,未分配的内存可能被设置为其它的值。

比如 VC 里著名的”烫烫烫“,或者 “屯屯屯”。

说到这儿,怎么少得了下面的这个小对联:

手持两把锟斤拷,口中直呼烫烫烫。


----------------------------------------

到目前为止的问题:

> 函数原型优化 luaU_optchunk

> 打印函数原型 luaU_printchunk

> dump 函数原型 luaU_dumpchunk

> ZIO 是什么 

> 语法析 luaY_parser

----------------------------------------


你可能感兴趣的:(lua,Lua4.0)