[AS3] Some observations regarding events

[SIZE=“4”]UPDATE[/SIZE]: I’ve put together a class called ActiveGraph to help other AS3 developers track memory usage in their apps. To skip to the ActiveGraph post, click here.

[SIZE=“1”]Hello. I think you’ll all find this interesting, please read on.

I’ve been peeved by the AS3 garbage collector, which has seems to often neglect to do its job. Until just now, I never could make an AS3 program that had no memory leaks, and now I know why. I’ve made some observations using a very basic Flash program, and I’d like you to conduct the test on your own machine and see if you get the same results. If you do, there are some pretty serious implications.

You can download my test program here: barebones.zip. I recommend that you read the code in it before compiling.

Flash lets you keep track of your program’s memory usage by getting the value of System.totalMemory. If you notice that your program slows down over time, you can try writing a function that traces System.totalMemory every once in a while. But if that function contributes to Flash’s memory usage, then the value of System.totalMemory will always go up.

I’ve discovered that the GC does not clean up some (or maybe all) events. An event is like any other object, and when it occurs, it takes up memory. And it looks as if the GC never touches this memory again! This means if you handle an event that happens over and over (like Timer or EnterFrame) or happens often (like MouseMove), event objects will keep being made and not deleted,and that’s a memory leak.

In the barebones.fla file, I’ve included two functions that track System.totalMemory and two more functions that print the data. Try using each of the three addEventListener lines of code toward the bottom (one at a time, of course) and running the program using print1();. Every time Flash needs another page of memory (4096 bytes, something you can observe yourself by modifying candidateB), it will output the System.totalMemory, followed by the iteration of the event you’re testing. If you run this Flash program again and again, the data it’s outputting should always be the same for the same event– regardless of Flash’s FPS, the speed of the timer, the size of the stage, etc.! The text file “memoryUsageStats.txt” holds statistics I’ve taken from barebones.swf running on my machine; see if they match yours.

So different events have different sizes, but their size isn’t affected by how often they occur. And because System.totalMemory for barebones.swf never decreases, we can conclude that the events aren’t being cleaned up by the GC. If my results can be repeated on other computers, then this means any AS3 program that updates constantly, like games, has a memory leak that cannot be circumvented.

One final observation I made is that the timeline in AS3 still has a memory leak of its own. In barebones.fla, try making an animated movieclip that contains a lot of shape data, and put it on stage. Then compare its memory statistics with the same program, but with a stop(); action in the movieclip’s first frame. I expect you’ll find that the animated movieclip leaks memory, too, so any Flash program with animation in it will leak memory, and there’s no clear way to stop that, either.

Comments would be appreciated. C:-)

EDIT: The above phenomena are, in fact, not memory leaks; they’re garbage that are (for the most part) deallocated when the totalMemory reaches Flash’s ceiling.

For a real memory leak to occur, the active memory of the Flash Player must be increasing when it doesn’t need to. This situation arises when objects are not properly dereferenced, thereby preventing the GC from removing them.[/SIZE]