lua-users home
lua-l archive

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


Hi.

I define a very simple user data with metamethods:

struct MyData
{
    int v;
};

#define MY_DATA_NAME "Data"

static int MyDataNew( lua_State *L )
{
    MyData *d=(MyData *)lua_newuserdata(L,sizeof(MyData));
    d->v=0;
    luaL_getmetatable(L,MY_DATA_NAME);
    lua_setmetatable(L,-2);
    return 1;
}

static int MyDataMethod( lua_State *L )
{
    return 0;
}

static const luaL_reg g_MyDataMeta[] = {
    {"__add", MyDataMethod},
    {0, 0}
};

int MyData_Register( lua_State *L )
{
    luaL_newmetatable(L,MY_DATA_NAME);
    luaL_openlib(L,0,g_MyDataMeta,0);
    lua_pop(L, 1);
    lua_register(L,MY_DATA_NAME,MyDataNew);
    return 0;
}

Then I run the following commands:
> =gcinfo()
17    29
> for i=1,100000 do a=Data() end
> =gcinfo()
21    34
> collectgarbage()
> =gcinfo()
17    34

I started with 17K and ended with 17K which is correct.

Now if I change the name of the metamethod from "__add" to "__gc":

static const luaL_reg g_MyDataMeta[] = {
    {"__gc", MyDataMethod},
    {0, 0}
};

 I get:
> =gcinfo()
17    29
> for i=1,100000 do a=Data() end
> =gcinfo()
464    511
> collectgarbage()
> =gcinfo()
226    452

The results suggest that if I don't provide a custom __gc method the system would free some resources automatically and if I do have custom __gc, I have to do it manually. However I couldn't find anything in the docs related to what it is.

The only custom __gc method in lua I could find is io_gc. Seems like it exhibits same problem:
> =gcinfo()
17    29
> for i=1,100000 do a=io.open("somenonexistingfile") end
> a=nil
> =gcinfo()
474    508
> collectgarbage()
> =gcinfo()
237    473

Looks like a memory leak. Any ideas how to fix it?

Thanks
Ivo