Can I Force the GC to Collect?

BlitzMax Forums/BlitzMax Programming/Can I Force the GC to Collect?

Gabriel(Posted 2007) [#1]
Is there some better way to force the Garbage Collector to Collect than using GCCollect()? Or indeed a better way to use GCCollect()?

I ask because my TrueVision3D module has to clean up after objects in delete methods. There is no user friendly alternative to this, sadly. If I don't do this, I'll have to completely ditch automatic garbage collection and force everyone to explicitly destroy everything. Which - even if I fancied it - goes a bit against the grain in a language which is supposedly superior because it has a GC.

So with my reasons justified, here's what I'm doing now. When I shut down the engine, the user may still have some TV objects floating around which haven't been disposed of, right? So I don't want those being called now, do I? Because the engine isn't there, so it will crash. So it seems like the best solution is to call GCCollect immediately before you shut down the engine, right? Then everything goes through, nothing is left behind, right? Doesn't work. Believe me, I wish it worked, but it doesn't. I can call GCCollect() as many times as I like but it won't flush some of these objects.

Hopefully not too many people are experiencing this, but if I am, they will soon enough. What else is there for me to do apart from call GCCollect()? ( and tell them to do the same, obviously. )

And no, I don't have any loose references flying around. The GC just seems to reach a point where it doesn't want to flush anything for a while, then a little time later, it will explode on a GCCollect trying to tell TV to free something that doesn't exist.


Dreamora(Posted 2007) [#2]
are you sure you didn't have any cyclic reference in.

Although even then: if you can still access them to call them and break something, how shall they actually be removed? They aren't garbage :)

So any chance you broke the ref count somewhere or forgot about assignements you do within your wrapping code that you don't break up? (like callink tlink.remove on a link that is a field of an object without setting the link = null afterwards to free the cyclic reference)


Grey Alien(Posted 2007) [#3]
GCCollect seems to work in simple cases for me. I've made cyclic references and seen it fail too.

Presume you read this too:

http://www.blitzbasic.com/Community/posts.php?topic=71840


Gabriel(Posted 2007) [#4]
are you sure you didn't have any cyclic reference in.

Yes, these particular objects only *ever* have one reference and it's most assuredly gone before the GCCollect call.

Presume you read this too:

Yes, but I had bad experiences with playing with the GC mode. Strange random bugs which go away magically without being fixed and then new ones which come in. Took me ages to track down the issues, and even now I'm not 100% sure what was wrong and if it's fixed. I figured a GCCollect() took precendence over aggressive automatied collection anyway, but perhaps I'm wrong.

Definitely no cyclic references though. It just seems that the GC doesn't want to collect them until a certain time after they're ripe for collection.


H&K(Posted 2007) [#5]
If I understand your problem, the Delete methods of TV3D MUST called before the TV3D engine can be closed, but the GC isnt bothering to call them?

so errrm guess ok

Create a load of dummy varaiables allocated to 0 or something, then unalloce them, then call GCCollect()


Dreamora(Posted 2007) [#6]
variables are not GC driven.
Only objects are.


Gabriel: I found out by accident (when checking for something on the german module board), that there is a GC mode -1, called "aggressive" in the c sources.
You might try and check what this one does.


I don't see a reason why it should not work, unless you are really trying to call a kill function in the delete of the object which is a highly critical action that you should never do
Destruction handling is something that you should call manually, the delete should only operate on its own data, not on external data as the destruction order is something you can NOT depend on.

ie
obj1 = null
obj2 = null

does not mean that obj1 delete is called before obj2, it might as well be vice versa or in any other order with other objects. (just as an example)
perhaps thats creating your problem.


Gabriel(Posted 2007) [#7]

obj1 = null
obj2 = null

does not mean that obj1 delete is called before obj2


No, it doesn't, but

obj1 = null
GCCollect()
obj2 = null

Should ensure that it is. ( Well not literally obviously as local variables don't go out of scope until the end of the function or whatever, but you get my point. I'm manually calling GCCollect after the object(s) I expect to be destroyed before I go any further, and they're not.


Create a load of dummy varaiables allocated to 0 or something, then unalloce them, then call GCCollect()

Sure, that's worth a shot. I'm assuming you mean dummy objects, but yeah, maybe it'll help.


H&K(Posted 2007) [#8]
Yep, I mean Objects. I in error nearly always refer to an instance as a "Variable" even if it has ten million fields.


Grey Alien(Posted 2007) [#9]
yep when doing GC testing it's important to make sure that you are not trying to GCCollect a local var as it won't be collected until it exits the scope. This threw me in early testing.