I like to think that I’m a responsible developer. I make good constructors and deconstructors to prevent memory leaks, I have fairly secure coding habits, I OOP the hell out of everything, and I do everything by-the-book.
Imagine my frustration, then, when all of my games (particularly my latest, Steambirds) have gigantic memory leaks. Like, 500+MB consumption in 5-30 minutes of gameplay.
At first I thought it was EventListeners keeping persistence on my trashed objects. I went through my code several times making sure I nabbed them all and set them to Weak.
Then I thought it was the weak listeners failing. My tests were showing orphaned objects still chugging away despite garbage collection making an observed pass. I’ve banged my head against several walls over the last year trying to figure this out, and in the end always giving up. “Restart the application if it gets slow!” was my only recourse. Flash doesn’t even let you force garbage collection on objects, so I couldn’t hack my way out of it.
Today I found a very interesting blog post. I always knew how the garbage collector worked; it traverses your tree of object references, and identifies any “islands”; that is to say, any objects that aren’t referenced by any variables in your code. At the end of it’s run, all the islands are trashed. What I didn’t know is that IF YOUR ISLANDS ARE BIG ENOUGH, FLASH GIVES UP AND ASSUMES IT’S NOT TRASH.
I guess by complexly-nesting my code, it resulted in something that was too much for the goddamn garbage man to handle. My games essentially think any object I ever create is for HOLDING ON TO FOREVER.
If you want some more technical data, I highly recommend you check out Tom Mason’s blog post on the topic. It was eye opening, to say the least. But now I have to go rewrite a shit-ton of code.