lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2008/11/14 Cheng, Long <long.x.cheng@gmail.com>:
> Hi all:
> We are building a large mmorpg game using lua as the main language. We
> have a game engine built on C++. With a customize C++/lua binding, we
> could export the whole game object system to lua, and we write all the
> logic control code in lua. All the C++ objects are referenced in lua as
> a lightuserdata, and their life cycle are controled by lua code (objects
> are created by lua call to C++, and recycled by lua GC). Now one problem
> I found is that, in most cases the C++ object is very big compare with
> the lightuserdata. When there are a big number of objects, most process
> memory are occupied by the C++ objects, but not counted in lua VM. For
> example, in a typical situation the whole server process uses around
> 300M bytes but in lua "collectgarbage("count")" shows only around 30M
> bytes. In such case lua GC fails to reclaim the dead objects, because
> lua VM does not think there are enough "wasted memory" to reclaim. I'm
> just wondering is there any way I can tell the GC algorithm how much
> "external" memory the lightuserdata is referencing? Or is there other
> "proper" ways to handle the objects life cycle? Thanks!

To have the garbage collector take into account the memory of your
objects you need to have that memory managed by the garbage collector.
To do that you need to make sure any allocated object is allocated
with lua_newuserdata. In C that is easy, you can create a malloc/free
interface around that function. In C++ this is slightly more tricky
since you need to override the new operator. You can find further
details on how to do that with google I guess.

As other mentionned this means you need to have full userdata, not
mere light ones. Once all your C++ objects are allocated through
lua_newuserdata you can make sure interdependencies and proper
deallocation of objects is done through the use of environment tables.
Each object (A) that point to another object (B) should have an
environment table (EA), with a reference to the other object (for
example EA[B] = true). If you clear a pointer remove the reference.
This is obviously costing a lot of memory (one table per C++ object
that contains pointers), but afaik this is the only way to have the
garbage collector properly account for C/C++ objects memory.