Garbage Collection

Subscribe to Garbage Collection 20 posts

avatar for Outstream Outstream 64 posts
Flag Post

So I know that java is known for it’s garbage collection system, but what about flash? I have used java since I started programming so I don’t know much about garbage collection.

What garbage collection does flash have?

What can I do to reduce “garbage”?

any other misc info is also appreciated

 
avatar for BobJanova BobJanova 855 posts
Flag Post

Flash is garbage collected and in a pretty similar way to Java or .Net. An object which is not reachable (i.e. is not referenced by something which can be reached from the stage) will, at some stage, be collected.

 
avatar for Ace_Blue Ace_Blue 1072 posts
Flag Post

If garbage collection is very important to you, know that the collector in Flash has a host of problems. Event listeners on objects prevent them from being collected, unless they are weak references, and even then I’ve seen a blog that claimed the collector still didn’t get to them. Same source also claims that if you have a large chunk of objects referencing each other but nothing else references it, and the chunk is large enough, the collector will just give up and assume it should be kept around.
Oh, and there’s no command to force garbage collection. Fun, eh?

I have not run any test to verify the above claims, so maybe I’m just propagating urban legends, but I know from monitoring my applications’ memory usage that:
1) The garbage collector isn’t all that zealous in its efforts to clean up, often leaving expired objects for several passes before finally collecting them.
2) Even on small projects for which I was careful to deallocate everything after use, memory usage still crept up slowly over time, seemingly linearly. I have no clue what’s causing this behavior.

 
avatar for Drakim Drakim 1140 posts
Flag Post
Originally posted by Outstream:

What can I do to reduce “garbage”?

Based on this comment I’m inclined to think you have misunderstood how Garbage Collection works.

You see, the whole point with GC, the only reason it was made, was so that you wouldn’t have to mark your objects for deletion. If you have a language without GC, you have to manually destroy every object when you don’t need them anymore. If you forget doing this the object remains in memory forever (called memory leak). The GC basically keeps an eye your objects and deletes them when it sees that you don’t need them anymore (for instance when nothing in your code interacts with this object anymore).

 
avatar for Outstream Outstream 64 posts
Flag Post
Originally posted by Drakim:
Originally posted by Outstream:

What can I do to reduce “garbage”?

Based on this comment I’m inclined to think you have misunderstood how Garbage Collection works.

You see, the whole point with GC, the only reason it was made, was so that you wouldn’t have to mark your objects for deletion. If you have a language without GC, you have to manually destroy every object when you don’t need them anymore. If you forget doing this the object remains in memory forever (called memory leak). The GC basically keeps an eye your objects and deletes them when it sees that you don’t need them anymore (for instance when nothing in your code interacts with this object anymore).

I know what garbage collection is… if I wanted an explanation I would have asked. What I meant was what can I do to insure that my objects get collected?

 
avatar for Outstream Outstream 64 posts
Flag Post
Originally posted by Ace_Blue:

If garbage collection is very important to you, know that the collector in Flash has a host of problems. Event listeners on objects prevent them from being collected, unless they are weak references, and even then I’ve seen a blog that claimed the collector still didn’t get to them. Same source also claims that if you have a large chunk of objects referencing each other but nothing else references it, and the chunk is large enough, the collector will just give up and assume it should be kept around.
Oh, and there’s no command to force garbage collection. Fun, eh?

I have not run any test to verify the above claims, so maybe I’m just propagating urban legends, but I know from monitoring my applications’ memory usage that:
1) The garbage collector isn’t all that zealous in its efforts to clean up, often leaving expired objects for several passes before finally collecting them.
2) Even on small projects for which I was careful to deallocate everything after use, memory usage still crept up slowly over time, seemingly linearly. I have no clue what’s causing this behavior.

I read that blog also, and wasn’t really sure if the claims he made were true. Thanks for the info!

 
avatar for Drakim Drakim 1140 posts
Flag Post
Originally posted by Outstream:

I know what garbage collection is… if I wanted an explanation I would have asked. What I meant was what can I do to insure that my objects get collected?

That’s the point, you don’t need to do anything. Objects are collected automatically. That’s what a garbage collector does, it collects object automatically.

It does so when the GC can “see” that you don’t need the object anymore. So if you for instance have an object in a variable, and then you change that variable to hold something else, the first object will be automatically garbage collected.


var myVariable = new Point(5,10); //create a point object

myVariable = new Point(3,3); //the first point object will now be garbage collected

myVariable = null; //the second point will now also be garbage collected

The only “gotcha” is that you might forget that you have references to the object lying around somewhere, but really really shouldn’t happen unless you have spaghetti code. There are also some nifty things like weak listeners, but those are another can of worms entirely.

 
avatar for NineFiveThree NineFiveThree 1370 posts
Flag Post
Originally posted by Outstream:

What can I do to reduce “garbage”?

Well, if you know what the garbage collection does you should know that.
Garbage is an object that’s eligible for gc.
If you want to reduce garbage, reduce the amount of objects that are/become eligible for gc.

 
avatar for truefire truefire 3011 posts
Flag Post

The only “gotcha” is that you might forget that you have references to the object lying around somewhere, but really really shouldn’t happen unless you have spaghetti code

It happens a lot more than you’d think when events are involved. An object can become ‘self sustaining’ if it’s got a non-weak-referenced listener.

class Blah() extends EventThing { function Blah() { addEventListener("ENTER FRAME", update); } function update(e:Event):Void {} }

new Blah(); //this blah lives out in the vast reaches of the RAM, running it's pointless update function for all eternity
 
avatar for BigJM BigJM 468 posts
Flag Post
Originally posted by Ace_Blue:

If garbage collection is very important to you, know that the collector in Flash has a host of problems. Event listeners on objects prevent them from being collected, unless they are weak references

I wouldn’t call that a problem so much as expected behaviour.

Originally posted by Ace_Blue:
Oh, and there’s no command to force garbage collection. Fun, eh?

There is this for the debug player: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/System.html#gc()

And, starting in FP11, this method for being able to suggest to the GC when a good time to finish mark-sweeping is: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/System.html#pauseForGCIfCollectionImminent()

And this for XML:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/System.html#disposeXML()

This is a good article abut GC in Flash:
http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html

 
avatar for BigJM BigJM 468 posts
Flag Post
Originally posted by truefire:

The only “gotcha” is that you might forget that you have references to the object lying around somewhere, but really really shouldn’t happen unless you have spaghetti code

It happens a lot more than you’d think when events are involved. An object can become ‘self sustaining’ if it’s got a non-weak-referenced listener.

class Blah() extends EventThing { function Blah() { addEventListener("ENTER FRAME", update); } function update(e:Event):Void {} }

new Blah(); //this blah lives out in the vast reaches of the RAM, running it's pointless update function for all eternity

I’m fairly certain that will be garbage collected eventually.

 
avatar for Drakim Drakim 1140 posts
Flag Post
Originally posted by BigJM:

I’m fairly certain that will be garbage collected eventually.

Nope it won’t. You have to specially mark it as a weak listener, otherwise it will never be collected.

 
avatar for Outstream Outstream 64 posts
Flag Post
Originally posted by truefire:

The only “gotcha” is that you might forget that you have references to the object lying around somewhere, but really really shouldn’t happen unless you have spaghetti code

It happens a lot more than you’d think when events are involved. An object can become ‘self sustaining’ if it’s got a non-weak-referenced listener.

class Blah() extends EventThing { function Blah() { addEventListener("ENTER FRAME", update); } function update(e:Event):Void {} }

new Blah(); //this blah lives out in the vast reaches of the RAM, running it's pointless update function for all eternity

These are the things I’m talking about, I learned that event listeners must be removed or be created with weak references to be collected. I’m wondering if there is anything else like this

 
avatar for BigJM BigJM 468 posts
Flag Post
Originally posted by Drakim:
Originally posted by BigJM:

I’m fairly certain that will be garbage collected eventually.

Nope it won’t. You have to specially mark it as a weak listener, otherwise it will never be collected.

No, you’re wrong. By fairly certain, I meant 100% sure ;) For one, the references in that example are cyclic so the GC will remove the object eventually. Two, the weakReference parameter of addEventListener is specifically designed for unbound functions and would never apply to class methods. If you don’t believe me you can invoke the GC yourself and see.

 
avatar for Outstream Outstream 64 posts
Flag Post
Originally posted by BigJM:
Originally posted by Drakim:
Originally posted by BigJM:

I’m fairly certain that will be garbage collected eventually.

Nope it won’t. You have to specially mark it as a weak listener, otherwise it will never be collected.

No, you’re wrong. By fairly certain, I meant 100% sure ;) For one, the references in that example are cyclic so the GC will remove the object eventually. Two, the weakReference parameter of addEventListener is specifically designed for unbound functions and would never apply to class methods. If you don’t believe me you can invoke the GC yourself and see.

So you’re saying it’s not necessary to remove event listeners?

 
avatar for BigJM BigJM 468 posts
Flag Post
Originally posted by Outstream:
Originally posted by BigJM:
Originally posted by Drakim:
Originally posted by BigJM:

I’m fairly certain that will be garbage collected eventually.

Nope it won’t. You have to specially mark it as a weak listener, otherwise it will never be collected.

No, you’re wrong. By fairly certain, I meant 100% sure ;) For one, the references in that example are cyclic so the GC will remove the object eventually. Two, the weakReference parameter of addEventListener is specifically designed for unbound functions and would never apply to class methods. If you don’t believe me you can invoke the GC yourself and see.

So you’re saying it’s not necessary to remove event listeners?

No, I never said that anywhere.

 
avatar for Outstream Outstream 64 posts
Flag Post

Why is it unnecessary in his example then?

 
avatar for truefire truefire 3011 posts
Flag Post

But what if the update function did have something in it, such as Main.game.update();

They only difference in the scenario is that the ‘dead object’ actually does something. (Causes our game to update! Very important!) We can’t just have it GC’d. You might respond with, “well it can see that the update function is doing something so it won’t remove it.” I’m fairly certain that the Flash Player is not that intelligent, but even if it WAS, this objct is still in ‘unreachable memory space’. Further more, what if, rather then Main.game.update();, we said var q:Int = 5;. In that case, it’s not actually doing anything meaningful (just creating, then disposing of a local-scope variable). Certainly the Flash Player isn’t able to evaluate this.

 
avatar for BigJM BigJM 468 posts
Flag Post
Originally posted by Outstream:

Why is it unnecessary in his example then?

Haha, I never said that either. Two people made a claim which is simply not true so I’m just trying to correct it. You certainly should remove event listeners from objects you expect will be garbage collected because you have no way of knowing when they actually will be.

Originally posted by truefire:

But what if the update function did have something in it, such as Main.game.update();

They only difference in the scenario is that the ‘dead object’ actually does something. (Causes our game to update! Very important!) We can’t just have it GC’d. You might respond with, “well it can see that the update function is doing something so it won’t remove it.” I’m fairly certain that the Flash Player is not that intelligent, but even if it WAS, this objct is still in ‘unreachable memory space’. Further more, what if, rather then Main.game.update();, we said var q:Int = 5;. In that case, it’s not actually doing anything meaningful (just creating, then disposing of a local-scope variable). Certainly the Flash Player isn’t able to evaluate this.

Anything that is unreferencable (word?) will be garbage collected eventually. It doesn’t matter what it’s doing. It’s your job to ensure that objects which are part of your program don’t get garbage collected.

 
avatar for BobJanova BobJanova 855 posts
Flag Post

The event listener thing is regarding event listeners that keep a reference alive, e.g.

class B {
 function attach(a:A) : void {
  a.attachEventListener(...);
 }
}

class A {
 ...
}

class Main {
 var a:A;

 function Main() {
  a = new A();
  var b:B = new B();
  b.attach(a);
 }
}

Now, that B object will never be collected (while Main is in scope), because the attachment of an event listener creates a reference in a to b. This is why you should always remove events attached to the stage (often done with ENTER_FRAME or mouse events), because they create a reference from the stage to your object and mean that your object can never be collected.