Part Three in a series.
After the last discussion regarding Flash and garbage collection, a bunch of us concluded that there are two types of garbage– garbage that is quickly collected, and cyclically referenced garbage that sits around for longer– and that the longer-lasting garbage usually consists of deleted DisplayObjects. So Flash games and systems that use complicated animation will have more “display garbage” hanging around, and though it’ll eventually be cleaned up, it might have an effect on your program’s performance. But why is there so much display garbage? I intended to find out, and I think I did. So naturally I’m sharing it with you.
I’ve created a class called Dissolver with a static dissolve() function. You pass it a DisplayObjectContainer, and it’ll recursively go through the display list of that object, dissolving all parent-child relationships. It doesn’t matter whether any of those objects are instances of sealed classes, it just works. It does a very nice job, but to make sure none of the objects make new children from the Timeline, any MovieClips are stopped. And it works! Fancy that.
Dissolver is a nice class, but it really doesn’t address this issue. However, by commenting out the removeChild() statements, I made dissolve() into a MovieClip-stopping system. I dissolved my entire display list, and with ActiveGraph running, I noticed the memory use was stable (aka, no garbage). So I figured that the Timelines in MovieClips might be making the display garbage.
And they do. If you have a symbol in one keyframe in any Timeline, and a blank keyframe sometime after it, the code Flash generates from the Timeline will delete the object in the earlier keyframe and make a new instance of it later. (And if you don’t have the blank keyframe, it won’t delete the object.) Want to make a ton of “display garbage”? Compile a Flash file with a MovieClip in frame one and a blank keyframe in Frame 2.
Why does Flash do this? Well, remember that the point of a Timeline isn’t always to have a short, looping animation. Sometimes a Timeline will be long, and will contain thousands of different objects. This makes it necessary for Flash to destroy objects when they’re no longer in the current keyframe– to relinquish memory for new objects.
It would be nice if Flash would give you an option to make a MovieClip symbol’s Timeline recycle symbols, but it doesn’t. I think I’ll submit a feature request. But if you want to reduce “display garbage”, you can do it by never using blank keyframes. Instead, add actions to your animations that set the visible property of your symbols to false, then to true when they need to show up, then to false again.
EDIT: Scratch that. It looks like the Timeline will still make garbage if you remove blank keyframes. The behavior of Timelines must be more complicated. Unless anyone else has any ideas, this means that games with heavy amounts of animated content are at the whim of the mark-and-sweep garbage collector.
If anyone wants to check out Dissolver, let me know and I’ll upload and link to it.