<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2010://34/tag:www.insideria.com,2009://34.37746-</id>
  <updated>2010-03-19T18:19:47Z</updated>
  <title>Comments for Memory Management with the Dictionary Object (http://www.insideria.com/2009/08/memory-management-with-the-dic.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2009://34.37746</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=37746" title="Memory Management with the Dictionary Object" />
    <published>2009-08-31T20:00:00Z</published>
    <updated>2009-08-31T20:00:00Z</updated>
    <title>Memory Management with the Dictionary Object</title>
    <summary>In my previous article I detailed the architecture for a video player that would switch between multiple players, using composition to support the same interface across each layer of the architecture. The architecture worked out really well, but when I...</summary>
    <author>
      <name>Tom Barker</name>
      
    </author>
    
    <category term="Blogs" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<p>In my <a href="http://www.insideria.com/2009/08/composition-and-the-player-swa.html">previous article</a> I detailed the architecture for a video player that would switch between multiple players, using composition to support the same interface across each layer of the architecture.
</p><p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="playerswapper.png" src="http://www.insideria.com/tbarker/playerswapper.png" width="510" height="445" class="mt-image-none" style="" />
</span>
</p><p>
The architecture worked out really well, but when I profiled the actual implementation I found there was an issue with memory management.  The general idea is that the PlayerSwapper object would instantiate a new version of the appropriate wrapper object and set that to it's <em><strong>player</strong></em> variable.
</p><p>
The problem was some of those players were external SWFs, and once loaded in, the Flash player wasn't releasing them.  As I profiled the application there was a steady increase in memory allocated as each video was played and a new player was instantiated.
</p><p>
To solve this I changed the functionality of the PlayerSwapper class a little.
</p><p>
I had the PlayerSwapper object keep a Dictionary of players - the Dictionary object is an associative array that keeps an object as the index.  I created an Enumerator to list all potential player types for reference, and used each Enum value as the Dictionary index and the player instance as the value at that index. 
</p><p>
In such a way I was able to check if a player was already instantiated - and if it was use it, but if it wasn't, to create it and store it in the Dictionary for future use as well.  This allowed me to slowly build to a memory plateau that never grew beyond the size needed for all players.  In fact since it only instantiated a player that it needed, depending on the play list, some players were never instantiated.
</p><p>
<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>

<span class="category1">private</span> <span class="category1">var</span> _client:ClientEnum;
<span class="category1">private</span> <span class="category1">var</span> _vo:VideoObject	
<span class="category1">private</span> <span class="category1">var</span> _playerDictionary:Dictionary
		
<span class="category1">public</span> <span class="category1">function</span> PlayerSwapper(w:<span class="category2">Number</span>=320, h:<span class="category2">Number</span>=240, <span class="category2">x</span>:<span class="category2">Number</span>=0, <span class="category2">y</span>:<span class="category2">Number</span>=0)
{
  _playerDictionary = <span class="category1">new</span> Dictionary(<span class="category1">true</span>);
}
		
<span class="category1">private</span> <span class="category1">function</span> createPlayers(c:ClientEnum):<span class="category1">void</span>
{			
  <span class="category1">var</span> tempPlayer:IPlayer
  <span class="category1">switch</span>(c.value)
  {
   <span class="category1">case</span> ClientEnum.A:
    tempPlayer = <span class="category1">new</span> PlayerAWrapper(<span class="category1">this</span>._vidW, <span class="category1">this</span>._vidH, <span class="category1">this</span>.<span class="category2">x</span>, <span class="category1">this</span>.<span class="category2">y</span>);
    <span class="category1">break</span>				
   <span class="category1">case</span> ClientEnum.B:
    tempPlayer = <span class="category1">new</span> PlayerBWrapper(<span class="category1">this</span>._vidW, <span class="category1">this</span>._vidH, <span class="category1">this</span>.<span class="category2">x</span>, <span class="category1">this</span>.<span class="category2">y</span>)
    <span class="category1">break</span>;				
   <span class="category1">case</span> ClientEnum.C:
    tempPlayer = <span class="category1">new</span> PlayerCWrapper(<span class="category1">this</span>._vidW, <span class="category1">this</span>._vidH, <span class="category1">this</span>.<span class="category2">x</span>, <span class="category1">this</span>.<span class="category2">y</span>)
    <span class="category1">break</span>;	
   <span class="category1">case</span> ClientEnum.D:
    tempPlayer = <span class="category1">new</span> PlayerDWrapper(<span class="category1">this</span>._vidW, <span class="category1">this</span>._vidH, <span class="category1">this</span>.<span class="category2">x</span>, <span class="category1">this</span>.<span class="category2">y</span>)
    <span class="category1">break</span>;			
   }
  <span class="category1">if</span>(!_playerDictionary[c]) _playerDictionary[c] = tempPlayer
}
		
<span class="category1">public</span> <span class="category1">function</span> getPlayer():IPlayer
{
  <span class="category1">var</span> tempPlayer:IPlayer		
  <span class="category1">if</span>(_vo.client != <span class="category1">null</span> &amp;&amp; _vo.releaseUrl != <span class="category1">null</span>)
  {	
    tempPlayer = <span class="category1">null</span>
    <span class="category1">if</span>(!_playerDictionary[<span class="category1">this</span>.client])	createPlayers(<span class="category1">this</span>.client)
     tempPlayer = _playerDictionary[<span class="category1">this</span>.client]
    }						
  <span class="category1">return</span> tempPlayer;					
}		
		
<span class="category1">public</span> <span class="category1">function</span> attachPlayer():<span class="category1">void</span>
{			
  _player = getPlayer()
  addChild(_player as Sprite)
  _player.source = source;			
}</pre>
</code>

</div></div>
</p>]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2009://34.37746-comment:2077453</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2009://34.37746" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html#comment-2077453" />
    <title>Comment from Richard Olsson on 2009-08-31</title>
    <author>
        <name>Richard Olsson</name>
        <uri>http://twitter.com/richardolsson</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://twitter.com/richardolsson">
        <![CDATA[<p>Pooling objects like this might be a good idea, but if the issue is really with wanting to free memory used by loaded-in SWFs, have you tried using Loader.unloadAndStop()? </p>

<p>This method (new in FP10) should make a loaded SWF (the one loaded by the Loader on which the method is executed) eligible for garbage collection, provided you haven't applied any event listeners, or in any other way stored a reference to it, or any of it's children, et c..</p>]]>
    </content>
    <published>2009-09-01T06:53:01Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2009://34.37746-comment:2077646</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2009://34.37746" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html#comment-2077646" />
    <title>Comment from Tim on 2009-09-01</title>
    <author>
        <name>Tim</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Im completeley out of the loop regarding flash and actionscript. might use some of the code here for my project <a href="http://ideenmanagement24.net/">ideenmanagement24</a> tho. cheers.</p>]]>
    </content>
    <published>2009-09-01T10:23:16Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2009://34.37746-comment:2077748</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2009://34.37746" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html#comment-2077748" />
    <title>Comment from Tom Barker on 2009-09-01</title>
    <author>
        <name>Tom Barker</name>
        <uri>http://www.oreillynet.com/pub/au/3751?all=yes</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.oreillynet.com/pub/au/3751?all=yes">
        <![CDATA[<p>@Richard - I'm familiar with unloadAndStop but my audience is still using 9.x player, so I can't reliably use player 10 features yet for something so essential.  The lowest version that I have to support is 9.0.28 - which is used by less than a percentage of my audience but still constitutes hundreds of thousands of users.</p>]]>
    </content>
    <published>2009-09-01T13:07:23Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2009://34.37746-comment:2082639</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2009://34.37746" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2009/08/memory-management-with-the-dic.html#comment-2082639" />
    <title>Comment from Accredited Online Universities on 2009-09-03</title>
    <author>
        <name>Accredited Online Universities</name>
        <uri>http://www.hattoss.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.hattoss.com">
        <![CDATA[<p>When using object caching, you create a cache of objects that the application can use. When the application is finished with these objects, you return the objects to the cache so that they can be reused again. This technique reduces the number of object instances created by the runtime, reduces the overall memory used when running the application, stabilizes the required resources to run the application and leads to better overall performance and scalability of the application when applied correctly.</p>]]>
    </content>
    <published>2009-09-04T06:25:52Z</published>
  </entry>

</feed
