Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you remove all references to a parent object, it is NOT necessary to remove its children, or listeners to the children objects, assuming there are no outside references to children objects.</p> <p>A mark-sweep garbage collector works by traversing the object graph, starting from the topmost object (i.e., the Stage). Snip off all paths to a portion of the graph, and that entire subgraph will be eligible for collection, regardless of any references the subgraph has amongst itself.</p> <p>First, let's consider just a display list hierarchy without events:</p> <pre><code>var clip:Sprite = new Sprite(); addChild(clip); var clip2 = new Sprite(); clip.addChild(clip2); // cleanup removeChild(clip); clip = null; clip2 = null; </code></pre> <p>The inner child clip2 will be garbage collected, even though we didn't remove it from its parent via <code>clip.removeChild(clip2)</code>. Since we removed all references to the parent <code>clip</code> and the explicit <code>clip2</code> reference, there's no way to access it, so it will be garbage collected. Therefore, it's not necessary to <code>removeChild</code> descendant clips. Just make sure you clear any outside references to them (in this case, <code>clip2</code>).</p> <p>Now let's imagine some events:</p> <pre><code>var clip:Sprite = new Sprite(); addChild(clip); clip.addEventListener(MouseEvent.CLICK, someListener); var clip2:Sprite = new Sprite(); clip.addChild(clip2); clip2.addEventListener(MouseEvent.CLICK, someOtherListener); // cleanup -- the same! removeChild(clip); clip = null; clip2 = null; </code></pre> <p>You might think that you have to remove the event listeners, but it actually isn't necessary. <strong>addEventListener creates a reference from the dispatcher to the listener</strong>. That is, adding listeners to children objects will not prevent their garbage collection. In this case, <code>addEventListener</code> makes a reference from clip to root, and clip2 to root. When garbage collection happens, the marker can't jump from root to clip, even though that listener is there. The reference is going the <strong>other direction</strong>, from clip to root! So the objects will still be garbage collected. Therefore, it's not necessary to remove the listeners in this case. That said, it doesn't hurt to do it if you are unsure.</p> <p>The only way listeners can prevent garbage collection is if a child clip is listening to a parent clip:</p> <pre><code>// from inside clip root.addEventListener(MouseEvent.CLICK, someHandler); </code></pre> <p>This listener creates a reference from root to clip, so you must either remove that reference or use weak references. Since you are using weak references, you don't have to worry about this, either.</p> <p>That indeed is a lot to keep track of, and it's easy to make a mistake, so <strong>it is good practice to remove listeners when you are done with them</strong>. You'll always be safe if you remove them. It's extremely important with weird native events that Flash dispatches for you, such as Event.ENTER_FRAME and KeyboardEvent.KEY_DOWN, but not because of garbage collection problems: Even if a clip has no references and is eligible for collection, it'll continue to receive ENTER_FRAME events until the garbage collector actually runs at some indeterminate point in the future. So you should ALWAYS remove ENTER_FRAME listeners.</p> <p>But in the case of a small object graph with simple MouseEvents, you'll be okay even if you don't bother to remove the listeners. They aren't hurting anything, and they'll no longer be dispatched when the clip is removed from the display list. You can just <code>removeChild</code> the parent clip and be done with it.</p> <p>If you want to peek at what is going on, it can be helpful to use the profiler tools in Flash Builder, FlashDevelop, or FDT to take a look at the memory usage. You can also use the <code>System.gc();</code> call to force the GC to run in debug mode if you want to test these ideas out.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload