如何在Lua中成功使用Loki的小对象分配器?

时间:2009-07-08 23:00:04

标签: memory-management lua loki

我在这里读到某个地方有人推荐使用Loki的Lua小对象分配器来帮助提高分配性能。我仔细阅读了“现代C ++设计”中的部分,我认为我已经对使用Loki有了足够的理解,除了不使用SmallObject - Lua只想要原始内存,所以我拿了第一次直接使用SmallObjAllocator

分配似乎正在起作用,但是一旦我尝试加载脚本(使用lua_load()和我自己的自定义阅读器,或使用luaL_loadfile()直接读取文件),一切都完全失败了。

这是我对SmallObjAllocator类的实现:

class MySmallAllocator : public Loki::SmallObjAllocator
{
  public:
    MySmallAllocator( std::size_t pageSize, 
                      std::size_t maxObjectSize, 
                      std::size_t objectAlignSize ) : Loki::SmallObjAllocator( pageSize, maxObjectSize, objectAlignSize ) 
    { 
    }
    virtual ~MySmallAllocator() 
    { 
    }
};
static MySmallAllocator alloc_(4096,64,4);

当我创建Lua状态时,我给它使用这个新分配器的分配函数:

masterState_ = lua_newstate(customAlloc_, &heap_);

void* customAlloc_( void* ud, void* ptr, size_t osize, size_t nsize )
{
  // If the new size is zero, we're destroying a block
  if (nsize == 0)
  {
    alloc_.Deallocate( ptr );
    ptr = NULL;
  }
  // If the original size is zero, then we're creating one
  else if (0 != nsize && 0 == osize)
  {
    ptr = alloc_.Allocate( nsize, false );
  }
  else
 {
   alloc_.Deallocate( ptr );
   ptr = alloc_.Allocate( nsize, false );
 }

 return ptr;
}

在这里我去加载文件:

int result = luaL_loadfile( masterState_, "Global.lua" );

如果我在Global.lua中有一个简单的for循环,系统永远不会从调用luaL_loaloadfile()返回:

for i=1,100 do
 local test = { }
end

有什么问题,我应该如何诊断,以及如何解决?

2 个答案:

答案 0 :(得分:4)

跳出来的问题是你的自定义分配器需要表现得像C的realloc()函数。在osize != nsize且两者都不为零的情况下,这是至关重要的。在这种情况下,realloc()的关键属性是它保留旧块的第一个min(osize,nsize)字节的值作为新块的开头。

你有:

    else
    {
            alloc_.Deallocate( ptr );
            ptr = alloc_.Allocate( nsize, false );
    }

放弃旧分配的所有内容。

这是指定的

  

分配器功能必须提供   功能类似于realloc,但是   不完全一样。

<{3}}的文档中的

答案 1 :(得分:0)

好的电话!我真的不明白realloc()做了什么,所以你让我走上正轨。我将重新分配部分替换为下面的代码,现在一切正常,但我现在的表现实际上比使用之前的HeapAlloc / HeapReAlloc / HeapFree更糟糕。

    void* replacementPtr = alloc_.Allocate( nsize, true );
    memcpy( replacementPtr, ptr, min(osize, nsize) );
    alloc_.Deallocate( ptr );
    ptr = replacementPtr;

我怀疑问题是因为Loki为每个Chunk使用malloc / free以及当大小为&gt;时GetMaxObjectSize()...