我怎样才能成功在Lua中使用Loki的小对象分配器?

我在这里读到有人推荐使用Loki的Small Object Allocator for Lua来帮助改善分配性能。我阅读了“现代C++设计”中的部分内容,我认为我已经了解了如何使用Loki进行此操作,但不包括不使用“SmallObject”-Lua只想要原始内存,因此我首先尝试直接使用“SmallObjAllocator”。

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

这是我使用MySmallAllocator类的实现:

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

出了什么问题,我该如何诊断它,以及如何修复它?

原文链接 https://stackoverflow.com/questions/1100992

点赞
stackoverflow用户68204
stackoverflow用户68204

我关注的问题是您的自定义分配器需要像 C 的 realloc() 函数一样运作。当 osize != nsize 且二者都不为零时,这一点至关重要。在这种情况下,realloc() 的关键特性在于保留旧块前 min(osize,nsize) 个字节的值作为新块的开头。

您的代码如下:

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

这将放弃旧分配中的所有内容。

这在 lua_Alloc 的文档中已经明确规定:

分配器函数必须提供与 realloc 类似的功能,但并非完全相同。

2009-07-09 07:40:05
stackoverflow用户88888888
stackoverflow用户88888888

好主意!我真的不理解realloc()的作用,所以你让我走上了正确的道路。我将重新分配部分替换为以下代码,现在一切都可以工作,但我的性能实际上比以前使用的HeapAlloc/HeapReAlloc/HeapFree要差一点。

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

我怀疑一个问题是Loki在每个Chunk以及当大小> GetMaxObjectSize()时使用malloc/free…

2009-07-09 18:50:57