August 02, 2006
MovieClips and garbage collection
While working on a game this week, I ran into an old nemesis...MovieClilp garbage collection. My SWF kept consuming more and more memory as the game progressed.
Here's my scenario:
1. attach background #1 on depth 1.
2. play level.
3. attach new background #2 at depth 2 offscreen, and scroll everything.
4. background #1 removeMovieClip()
5. play level.
6. attach new room 3 bg on depth 3 offscreen, scroll ... etc.
So I was placing a new movieclip on the stage at a higher depth and then removing the old one, and memory was leaking, over 1MB every time I did this scroll. The background clips are set to cacheAsBitmap after being attached.
My theory is that even though the previous background clip was removed (and it was actually removed...I checked it), Flash was still caching the memory required to render the clip. I even tried deleting the movieclip object after removing it. No help.
I changed the code, so that I always load the new BG into depth 2, and move the existing BG clip to depth 1, always using just these two depths. This minimized the damage, because now it seems that by only using these two layers of rendering, Flash will only consume RAM for backgrounds it has never attached before. If I reuse a background over again, the RAM is not consumed, presumably because Flash has already cached it, and the game's memory usage eventually reaches a point where it levels off.
Another odd point: The standalone Flash player seems to drop virtually all of its RAM resources when you minimize it. When you restore, the RAM usage is still smaller than when you started. Is it forcing the garbage collector to clean up at this point?
If so, why is there not a way for me to make this happen ON DEMAND? Why can I not cleanup a bunch of objects (say, at the end of a level, or when the player loses the game), and call something like _global.flush() to force this garbage collection to happen?
If I have 12 backgrounds in my game, Flash seems to cache each one for eternity, requiring over 12MB of RAM, even though you never have more than 2 backgrounds displayed at any one time. This makes no sense to me...
Posted by andy at August 2, 2006 11:27 AMHave you tried disabling cacheAsBitmap before you remove it? It may 'trick' Flash into cleaning up the cached bitmap.
Oh, and garbage collection is often done (at least in other garbage collected runtimes) when an app in minimized (and sometimes when it simply loses focus). Sometimes this is the result of the app entering an idle thread for a long time which triggers the garbage collection, and sometimes it's simply because the app is specifically scheduled to garbage collection on minimize.
Troy:
I actually did try turning off the cacheAsBitmap before removing it, with no success.
I guess I am not so surprised that Flash cleans up when minimized, I just with there was a way I could force that via code.
I got the exact same problem than you!
http://www.laflash.org/forum/showthread.php?p=6900#post6900
I got the exact same problem than you...but with arrays.
And sicovered (as you ;-) that strange behavior with minimized SWF
http://www.laflash.org/forum/showthread.php?p=6900#post6900