3

Having a problem with objects, not needed any more but still having references. Result: size of allocated memory is constantly growing due to not collected objects.

How to solve this sort of problem? Is there any way to find objects with only one reference, or objects with lifetime more than some value? Or any another solution?

Using Lua 5.1 and C++ with luabind.

Thanks.

Kara
  • 6,115
  • 16
  • 50
  • 57
kFk
  • 409
  • 6
  • 13
  • 1
    Are you by any chance keeping or leaking luabind::object instances? – sbk Dec 17 '09 at 17:31
  • Maybe keeping. Not leaking, because all luabind::object instances are created in stack and there is no such leaks in C++ code. – kFk Dec 18 '09 at 08:52

2 Answers2

5

As someone is mentioning here, you can try using weak tables.

If you have some code like this:

myListOfObjects = {}
...
table.insert(myListOfObject, anObject)

Then once anObject stops being used, it will never be deallocated since myListOfObjects still references it.

You could try removing the reference in myListOfObjects (setting the reference to nil) but a simpler solution is declaring myListOfObjects as a weak table:

myListOfObjects = {}
setmetatable(myListOfObjects, { __mode = 'v' }) --myListOfObjects is now weak

Given that setmetatable returns a reference to the table it modifies, you can use this shorter idiom, which does the same as previous two lines:

myListOfObjects = setmetatable({}, {__mode = 'v' }) --creation of a weak table
kikito
  • 51,734
  • 32
  • 149
  • 189
  • Weak tables is a good mechanism, but how to find proper objects to use in weak tables? There is about 2Mb of lua code in project and it's problematically to find what objects are not deallocated and still has a reference. Transforming all tables into weak tables will cause objects premature destroying. Also tables are mostly used to take ownership of objects and to free them only when it's necessary. Problem is that not all references are released and i cant' find them. – kFk Dec 19 '09 at 17:13
  • If you are not sure about what tables should be weak, then your only way of working is to set the all references to nil when they stop being useful. I recommend that you implement a "destructor" method for all your "classes" (types of tables). This destructor method should be called on objects that are not needed any more, and should equal their references to nil. Also, for "list of objects", implement a "liberate" method that assigns nil to references. – kikito Dec 21 '09 at 10:54
1

I'm not certain about integrating it with C++ but it sounds like the garbage collector isn't being given an opportunity to run.

In your lua you could try explicitly invoking it and see if that helps. There is a function in the core apis collectgarbage(opt [, arg]).

Bryan McLemore
  • 6,438
  • 1
  • 26
  • 30
  • Garbage collection runs periodically and doing it's job well. But it does not collect objects with existing references. There is a lot of such objects and I can't find them. – kFk Dec 17 '09 at 15:35
  • Are you suffering from circular reference problems? – Bryan McLemore Dec 17 '09 at 16:16
  • Does lua solves circular references correctly? If no, it may be the reason. – kFk Dec 18 '09 at 08:50
  • Did you try using weak tables? – Dave Berk Dec 18 '09 at 11:02
  • I'm not sure if they do or not by default. I'm used to working inside of WoW which I think has a tweaked implementation of the garbage collector. Using weak references like Dave mentioned could help you get around it. – Bryan McLemore Dec 18 '09 at 14:54
  • Problem is to find where to use weak tables. Please see my answer in comments to egarcia. – kFk Dec 19 '09 at 17:15