GCCollect wont collect if method called
BlitzMax Forums/BlitzMax Programming/GCCollect wont collect if method called
| ||
in this simple example, if the method on tObj1 is called, the GC will not collect. if its not called, it will. there is nothing in the method to increase the reference count so calling the method should not affect GCCollect().SuperStrict Framework BRL.Basic Type tObject Method A:String() Return "tObject.A()" EndMethod Method Delete() Print "tObject gone!" EndMethod EndType GCCollect() Print GCMemAlloced() Local tObj1:tObject=New tObject GCCollect() Print GCMemAlloced() ' with this line running, the object is not collected. ' comment this line and it works. Print tObj1.A() tObj1=Null GCCollect() ' if tObj1.A() was called the object doesnt collect Print GCMemAlloced() |
| ||
this is interesting. if i add the code:Local objptr:Byte Ptr=Byte Ptr(tObj1) objptr=Null anywhere after tObj1 is created, the GC works as expected. |
| ||
I dont think this is a bug but more a situation based upon the state of the Call Stack and the CPU Registers. Local variable Objects are not reference counted so as far as the GC is concerned just setting it to NULL wont force clean up until the Scope from which the varible was declared is popped off stack. That will guaranetee it gets cleaned up next time GCCollect is called. In context of stact frame it may or may not get cleaned up as you found by adding the additonal code. Due to the way the local stack frame and registers might be effected. When you declare local varibles inline like your example, the variable exists in the stack context of that function since all a BMAX application is is a function called by the startup code all local variables declared are in scope of that function on the stack. Calling other functions GCCollect Pushes the resisters on stack so when Garbage Collector scans the stack it might still think the local variabls are alive, as its still on the stack or in a register. Hense the seemingly random behavior. If you want to see what I mean change the variable to global in your example and what happens. Play with this example SuperStrict Framework BRL.Basic Type tObject Method A:String() Return "tObject.A()" EndMethod Method Delete() Print "tObject gone!" EndMethod EndType GCCollect() Doit() GCCollect() End Function DoIt() Print "In Doit" Local tObj1:tObject=New tObject GCCollect() ' Comment out this line to see changed behavior Print tObj1.A() tObj1=Null GCCollect() Print "Exit Doit" End Function It can be confusing but the GC works just dont assume setting or rely on setting varibable to NULL and calling GCCollect() will imidiately clean up. It will be eventually, but you can rely on it. Doug Stastny |
| ||
I had thought that we had been told that in a situation like this the local instance would mean that the object isnt collected straight away. That is, that in a "Test" situation the object appears to still exist, but after a few calls to other functions and stuff, (ie real application), the object would be collected? |
| ||
@Doug - thx for the inside info. i figured telling the GC to collect would... well collect any released objects at the time its called but it looks like certain situations still cause a delay. i guess the problem here is (me in) that GCCollect() doesnt quite have the functionality i was expecting it to have. again, thank you for the clarification. it is very much appreciated. |