WHY does Context become a GCRoot?

forbetter100's Avatar

forbetter100

20 Dec, 2012 10:52 AM

I appreciate Robotlegs very much, but recently a GC problem came to me. I failed to dispose context object by just set the reference null.With the help of FB profile tool, I find that context object appears to be a "GC Root".
To figure it out, I wirte a simple class, which creates a context obj and leave it unreachable.Here is the detail of this class:

public class MemoryLeak extends Sprite

{
    public function MemoryLeak()
    {
        makeAndDrop();
    }

    public function makeAndDrop():void{
        var _context = new Context(this);
        _context = null;
    }
}

When I ran this class, I hoped it be disposed by GC, but it didn't work(most times, not everytime). And the profile tool show me this instance is a GCRoot. I read some articles about GC, but few of them mention GCRoot itself. Could anybody tell me why and thank you so much!

  1. Support Staff 1 Posted by Ondina D.F. on 20 Dec, 2012 12:41 PM

    Ondina D.F.'s Avatar

    Hi,

    First of all, having the context variable scoped locally inside a function is not a good idea. Sooner or later it will get garbage collected and your app won’t work anymore. See this:
    https://github.com/robotlegs/robotlegs-framework/wiki/Common-Proble...
    If you already knew that, and you only experimented with a locally scoped context, then forget what I’ve just said :)

    Try this:

    private function initContext():void
    {
        var _context:SomeContext = new SomeContext (this);//bad
    }
    
    private function collectGarbage():void
    {
        System.gc();
        System.gc();
    }
    

    And then call collectGarbage() from somewhere in your code, for example by clicking on a button. Of course, there is a „run garbage collection“ button in your Flex Profiler too, but, for some reason, it’s not always working.
    You have to force the garbage collection, because flash player runs the gc only when it needs additional memory.

    If you already tried this and the context doesn’t get gc-ed, it means that you still have some references to it, keeping it alive.

    Ondina

  2. Ondina D.F. closed this discussion on 20 Dec, 2012 12:44 PM.

  3. Ondina D.F. re-opened this discussion on 20 Dec, 2012 12:44 PM

  4. 2 Posted by forbetter100 on 20 Dec, 2012 12:59 PM

    forbetter100's Avatar

    Thank you for replying. I have the context variable scroped only to experiment and hope it would be collected preferentially.
    But what I'm more concerned is why context object becomes a gc root in such cases, it's so weird.Sometimes it is collected, but in most times, flex profile shows that this object is a gc root(even if I called System.gc() twice). Could you tell me more about this? Thank you !

  5. Support Staff 3 Posted by Ondina D.F. on 20 Dec, 2012 02:55 PM

    Ondina D.F.'s Avatar

    You’re welcome!
    As I said in my previous post, you have to force the gc, if you want it to run at a certain point in time (in debug mode). Sometimes FlashPlayer runs the gc immediately, sometimes at a later time, that’s why you can see an instance of the context being kept alive at times.

    Make a very simple application, having just the root display object (s:Application or s:WindowedApplication) and a configuration class extending Context. Then have just this function in your root view (Application):

    private var context:SomeContext; //where SomeContext extends Context

    private function initContext():void
    {

    context = new SomeContext(this);
    

    }

    And a function that is forcing the gc on demand, as in my previous post.(calling gc twice!!)
    Run the profiler, and you’ll see that after forcing the gc, the context is gone. No instances, no references whatsoever.
    You can see that in the Live Objects list already: after forcing the gc, the number of context instances will be zero. Maybe you took a memory snapshot before the context got gc-ed, and of course you could see it listed. Make sure you call the gc twice, so the number of instances = = 0 inside Live Objects, then take a memory shot, and you’ll see that the context is gone.

    Be assured that the context will get gc-ed, if you don’t have any other references to it!!! Believe me :)

    Just in case you didn’t know about System.pauseForGCIfCollectionImminent() and gc is important to you not only for testing:
    http://blogs.adobe.com/cantrell/archives/2011/10/providing-hints-to...
    http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/...

    Bellow a bunch of articles about gc. Enjoy ;-)

    1
    http://gskinner.com/talks/resource-management/
    http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html
    http://www.adobe.com/devnet/flashplayer/articles/garbage_collection...

    2
    http://office.realeyesmedia.com/blogs/jun/?p=61
    http://office.realeyesmedia.com/blogs/jun/samples/360Flex/360_Slide...

    3
    http://blogs.adobe.com/aharui/2007/03/garbage_collection_and_memory...
    http://blogs.adobe.com/aharui/2008/09/using_the_flex_builder_3x_pro...

    4
    http://blog.flexmonkeypatches.com/2007/03/28/flash-player-memory-ma...

    5
    http://www.insideria.com/2008/03/flex-performance-memory-manage.html

    6
    http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-coll...

    7
    http://elromdesign.com/blog/2008/03/15/boost-flex-performance-with-...

    8
    http://flex.sourceforge.net/manual/The-Default-Memory-Management.ht...

    9
    http://roshantitus.blogspot.com/2008/11/flex-memory-management.html

    10
    http://www.nutrixinteractive.com/blog/?p=132

    11 Flash Player Mental Model - The Elastic Racetrack <-interesting
    http://www.onflex.org/ted/2005/07/flash-player-mental-model-elastic...

    Cheers,
    Ondina

  6. Ondina D.F. closed this discussion on 24 Dec, 2012 03:47 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac