Mar 25 2009
Some System.gc() and System.totalMemory Tips
When profiling a Flash or Flex application it’s sometimes useful to explicitly request that the player VM perform garbage collection. When used correctly this can help identify and track down memory leaks.
Some quick tips:
- System.gc() is asynchronous! I can’t tell you how many times I’ve seen developers make the call to gc() and then immediately query System.totalMemory! I’ve also seen people call it twice in a row (just to make sure it sticks ??) . Internally System.gc() simply queues up a garbage collection pass for the next frame interval. So make sure you query totalMemory on the next frame (listen for enterFrame), or use callLater if within a Flex application.
- System.gc() only works in a debugger player, and is a noop in the release build of the player. If you must do release mode profiling (which I highly recommend), you can utilize a well-known hack to force the player to garbage collect. Of course you do not want to make use of this in a production application, and the usual disclaimer applies, specifically this hack is not guaranteed to work in future versions of the player runtime.
Keep in mind that the release mode GC hack is in fact synchronous, however in this case the internal player code also queues up additional collection for the next frame interval so it’s best practice to wait a frame even then, such that anything pinned in memory due to just being on the callstack can be cleaned up.
1 2 3 4 5 | // Release mode gc(). try { new LocalConnection().connect('_noop'); new LocalConnection().connect('_noop'); } catch (e:*) {} |
At times it’s useful to make use of other tools to glean the total memory used by the player. I recommend testing within a standalone release player and leveraging Process Explorer and its ‘private bytes’ metric when on Windows, or Activity Monitor’s ‘private memory’ metric on OS X. Steer clear of Task Manager, as it incorporates uncommitted virtual memory that may or may not be used and is lazily reclaimed by the OS.
The next major release of the player will provide a new API which will more accurately reflect the cumulative memory in use by the player.
Nice one Corey thanks for the useful insight!
about calling the gc twice one for mark and one for sweep i think!
@John, right, but internally the first call only sets a flag and hints to the GC to collect on the next cycle. The second call is useless in that case (just sets the same flag).
Great article, I’ve found over the years that gc is improving tremendously (in flash player overall) and your last point of how much a release build can differ from a debugger player is greatly missed by many. The last few years I’ve found that if I can keep the debugging version that I’m building within a happy medium, my release builds are that much better.