Mar 25 2009

Some System.gc() and System.totalMemory Tips

Published by Corey at 10:54 am under Technology, Work

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:*) {}
  • System.totalMemory does not reflect all of the memory the player instance allocates. totalMemory is useful in most cases, since it reflects all of the memory that the internal player’s custom allocator has been asked to allocate for the bulk of the internal player constructs (inclusive of all script objects). Keep in mind however that not everything allocated in the player is allocated by the internal allocator, nor reported through totalMemory…namely anything allocated by OS system calls, memory associated with platform bitmap data, and the JIT buffer associated with the Actionscript VM.
     

    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.

  • Not all players and SWFs are created equal. Memory usage of a debugger player rendering a debug SWF will be significantly higher than the same player rendering a release build of the same SWF. It also holds true that the memory usage of a debugger player rendering a release SWF will be significantly higher than a release player rendering the same release SWF. So long story short, it’s always best to do your profiling and performance testing in a release player (against a release SWF) when at all possible.

5 Responses to “Some System.gc() and System.totalMemory Tips”

  1. Dougon 26 Mar 2009 at 7:31 am

    Nice one Corey thanks for the useful insight!

  2. Johnon 08 Apr 2010 at 2:46 pm

    about calling the gc twice one for mark and one for sweep i think!

  3. Coreyon 08 Apr 2010 at 3:36 pm

    @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).

  4. NooRoticon 02 Aug 2010 at 4:33 pm

    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.

  5. Sketchon 07 Jun 2012 at 12:12 pm

    System.privateMemory is the new API for memory used by the entire player environment, AIR/ADL or FlashPlayer (i hear it reports memory used by the browser also…)

    System.freeMemory is useful too

    privateMemory does not go down immediately after garbage collection
    based on light testing i speculate that it gradually goes down over the next 10 seconds besides what is reserved for improved performance of future memory use in freeMemory.

Trackback URI | Comments RSS

Leave a Reply