Garbage Collection and TLFTextFields
I’m writing this blog post as a warning to other Flash Developers.
During the last few weeks we’ve been incredibly busy trying to actually finish off our upcoming Flash game Sky Panda (it's changed a bit since then). One of the biggest bullet points on my to-do list was simply called “optimisation” and it got left pretty much right until the end. Encapsulated within this simple looking bullet point are a number of things, but the one I want to talk about at the moment is Garbage Collection.
AS3 is a garbage collected language, which means in simple terms that every now and then, as if by magic, the garbage collector will run through your created objects and hopefully clean up anything that is no longer in use. When it works it’s lovely, when it misbehaves (tweens!) it’s annoying, when it just doesn’t seem to be working at all it’s absolutely infuriating.
Here's a "before" screenshot of Sky Panda being monitored in Adobe Scout. Over the course of this Scout recording I switch back and forth between the Title and In Game screens, each time I go back to the In Game screen the AS3 execution time increases. Over a long enough period of time the Garbage Collector too becomes a real issue, collecting more and more every frame.
There's clearly a problem here.
Usually the advice on how to properly facilitate garbage collection is simple - remove all event listeners, null all references. If it’s not working you’ve probably forgotten to null out a reference somewhere. In this case, that just wasn’t enough. After a week of tearing my hair out, going over the code with a fine toothed comb looking for remaining references and hundreds of unsatisfying Google Searches I stumbled across this, at what to me felt like the very end of the Internet.
From that page I learned that TLFTextFields that have been created in the Flash Authoring Environment don’t get Garbage Collected.
Yes, you read that right. The default TextField Type in Flash CS5.5 does not get Garbage Collected if you actually use Flash CS5.5 to create them! What?!
To avoid this problem you must either use Classic Text in place of the TLF Text or you can create TLF Text dynamically using AS3. In Sky Panda we dynamically created Classic Text Fields instead of TLF ones because the new TLF ones were giving us other unique problems when trying to edit their values. Avoid the headaches where you can.
Here's an "after" screenshot from Adobe Scout, again I was switching furiously back and forth between the Title Screen and In Game screen.
Just to come clean here, there might be one or two other small optimisations besides swapping the text that I wrote on my journey of discovery, but the bulk of the problem was indeed the text.
If you're struggling to determine if your objects have been collected or not, then I'd like to direct your attention to The MemoryTracker Object which is a very clever and easy to use bit of code that has become an essential part of my toolkit, right alongside Adobe Scout.
I won't go into how it works in detail here, but basically you just pass it an object you're suspicious of, plus a label of your choosing, then it will trace out lists of all those objects that have not yet been cleaned up.
This was such a pain for me to figure out and I'd hate for anyone else to have to go through the same thing. I hope this blog post comes in useful for somebody!