<?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/2008/03/flex-performance-memory-manage.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.23037-</id>
  <updated>2009-11-16T15:51:49Z</updated>
  <title>Comments for Flex Performance, Memory Management, &amp; Object Caching (http://www.insideria.com/2008/03/flex-performance-memory-manage.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.23037</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.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=23037" title="Flex Performance, Memory Management, &amp; Object Caching" />
    <published>2008-03-05T18:03:23Z</published>
    <updated>2008-03-06T15:04:34Z</updated>
    <title>Flex Performance, Memory Management, &amp; Object Caching</title>
    <summary>The responsiveness and performance of a Flex application directly relates to what is being displayed onscreen.   The more that is happening, the slower the application will respond.   In most cases, you won&apos;t run into this scenario.  If you are dynamically adding LOTS of UIComponents, then this tip will help you create applications that perform very well under heavy load.</summary>
    <author>
      <name>Andrew Trice</name>
      
    </author>
    
    <category term="Blogs" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<p>The responsiveness and performance of a Flex application directly relates to what is being displayed on screen.   The more that is happening, the slower the application will respond.   In most cases, you won't run into this scenario.  If you are dynamically adding <strong><u>LOTS </u></strong>of UIComponents, then this tip will help you create applications that perform very well under heavy load.</p>

<p>One of the most computationally expensive operations in the Flex component life cycle is the constructor and initialization routine.  If you are adding and removing lots of complex components, this can become very taxing on the system, and reduce overall application performance.  The more complex the component, the more taxing it will be.   One way to reduce the impact that this has on your system is through object caching, (also known as <a href="http://en.wikipedia.org/wiki/Object_pool" target="_blank">object pooling</a>).  </p>

<p><strong>Reduce, Reuse, Recycle</strong><br />
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 (less spikes in both cpu and memory), and leads to better overall performance and scalability of the application when applied correctly.</p>

<p>Here is a sample project that demonstrates this technique and its benefits...  There are two applications in the project.  Both have identical functionality, however one implements object caching, and one does not.   The sample applications demonstrate the memory and performance impacts by creating and removing 100 "CircleRenderer" objects on every "ENTER_FRAME" event.  </p>

<p>In some senses, this example is very extreme because we are adding and removing 100 child objects in every "ENTER_FRAME" event.   In other senses, this example is basic because the CircleRenderer itself is a very simple object.  Objects that are more complex can require more resources to be created & rendered, even if they are not added and removed as frequently as this example.   The CircleRenderer is a simple object that extends from UIComponent.   It draws a circle, with a variable color and radius, and creates three TextFields inside of it.   One contains a UID string, one displays the color, and one displays the radius value.  All radii, color and UID values are randomly generated within the application.</p>

<p>First, let's look at the ObjectCache class, then we will get into the difference this technique makes:</p>

<pre>public class ObjectCache
{
	private static var cache : ArrayCollection;
	private static const preCache : int = 100;
	
	public static function getRenderer() : CircleRenderer
	{
		var renderer : CircleRenderer;
		
		if ( cache == null )
		{
			cache = new ArrayCollection();
			
			for ( var x : Number = 0; x < preCache; x ++ )
			{
				renderer = new CircleRenderer();
				cache.addItem( renderer );
			}
		}
		
		if ( cache.length <= 0 )
			renderer = new CircleRenderer();
		else 
			renderer = cache.removeItemAt( 0 ) as CircleRenderer;
			
		return renderer;
	}
	
	public static function setRenderer( renderer : CircleRenderer ) : void
	{
		cache.addItem( renderer );
	}
}</pre>

<p>You can see that there are two publicly exposed static methods on the ObjectCache class: getRenderer and setRenderer.   The "getRenderer" method is used to retrieve a CircleRenderer instance from the cache.   If the cache has not been initialized, it will precache 100 CircleRenderer instances in the cache.   If the cache contains a renderer instance, it will remove a renderer from the cache and return it.   If the cache is empty, it will simply return a new renderer.   The "setRenderer" method just returns the renderer to the cache of available renderers.</p>

<p>Now, lets get into the application itself...</p>

<p>On every "ENTER_FRAME" event, the "No Cache" application removes all of the circle renderers from the container, and creates 100 new renderers:</p>

<pre>private function onEnterFrame( event : Event ) : void
{
	circlesContainer.removeAllChildren();
	
	for ( var x : Number = 0; x < children; x ++ )
	{
		var renderer : CircleRenderer = new CircleRenderer();
		RendererUtil.updateRenderer( renderer );
		circlesContainer.addChild( renderer );
	}
}</pre>

<p>On every "ENTER_FRAME" event, the "Cache" application removes all of the circle renderers from the container and returns them to the cache.  It then adds 100 renderers to the container that are retrieved from the cache.</p>

<pre>private function onEnterFrame( event : Event ) : void
{
	while ( circlesContainer.numChildren > 0 )
	{
		ObjectCache.setRenderer( circlesContainer.removeChildAt( 0 ) as CircleRenderer );
	}
	
	for ( var x : Number = 0; x < children; x ++ )
	{
		var renderer : CircleRenderer = ObjectCache.getRenderer();
		RendererUtil.updateRenderer( renderer );
		circlesContainer.addChild( renderer );
	}
}</pre>

<p>The "RendererUtil.updateRenderer" method simply sets all the randomly generated values for the renderer component.</p>

<p>Now, the results...</p>

<p>In the application, there is also a performance monitor class, inspired by <a href="http://www.lynchconsulting.com.au/blog/index.cfm/2007/3/19/Viewing-Flash-Player-Memory-Usage" target="_blank">this one</a>.   This performance monitory tracks the current memory usage, the peak memory usage, and the history of the memory usage.   <em><strong>Note:</strong>  the performance monitor uses System.totalMemory to calculate the amount of memory used.  This is the entire memory used by the flash player, so don't run both examples at the same time, or else your results will be skewed!</em></p>

<p><a href="http://www.insideria.com/upload/2008/03/flex_performance_memory_management_object_caching/performanceComparison.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/flex_performance_memory_management_object_caching/performanceComparison.jpg" alt="performanceComparison.jpg" title="Click to enlarge" width="400"/></a></p>

<p><br />
On my machine <em>[Inte(R) Core(TM)2 Duo 2 GHz, 2 GB RAM]</em>, I ran these examples for 2 minutes apiece.   The cached version had a peak memory usage of 10907648 bytes, and the non-cached version had a peak of 19681280 bytes.  That's a difference of 8773632 bytes, or 8.36 MB.   Not only does the cached version use less memory, it also has more consistent memory usage and cpu usage. (I wish I could track cpu usage in Flash/Flex, but unfortunately I haven't found a way yet.)   </p>

<p>Both graphs shown here have the same horiztonal time scale (although the vertical scale is dependant upon the peak value).  The two graphs show that the non-cached version had more frequent, and more drastic memory spikes, thus more frequent garbage collection.</p>

<p>You can run the applications yourself here (warning-CPU intensive code): <br />
<strong>Cache:</strong><br />
<a href="http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/Cache.html" target="_blank">http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/Cache.html</a><br />
<strong>No Cache:</strong><br />
<a href="http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/NoCache.html" target="_blank">http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/NoCache.html</a></p>

<p>You can view the source at:<br />
<a href="http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/srcview/" target="_blank">http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/srcview/</a></p>

<p>You can download the source at:<br />
<a href="http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/srcview/ObjectCache.zip" target="_blank">http://www.cynergysystems.com/blogs/blogs/andrew.trice/objectcache/srcview/ObjectCache.zip</a></p>

<p>Leave a comment!<br />
<a href="http://www.cynergysystems.com/common/contact.jsp?context=Blogs" target="_blank">Or, contact me directly here</a></p>]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015666</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015666" />
    <title>Comment from Andrew Trice on 2008-03-05</title>
    <author>
        <name>Andrew Trice</name>
        <uri>http://www.tricedesigns.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.tricedesigns.com">
        <![CDATA[<p>An additional note:   This is the same concept used by Flex lists and datagrids internally for their item renderers. </p>]]>
    </content>
    <published>2008-03-05T18:24:03Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015668</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015668" />
    <title>Comment from Rhys Tague on 2008-03-05</title>
    <author>
        <name>Rhys Tague</name>
        <uri>http://www.rhycom.com.au</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.rhycom.com.au">
        <![CDATA[<p>Hey Andrew,</p>

<p>Great post!</p>

<p>Making sure that you Flex application is running at its optimum functionality is a major concern when dealing with large applications.</p>

<p>I can't see where someone would add that many UIComponents to the stage to get a heavy load like that if building a real application. Maybe if you were tracking data and using custom visualizations to show the data being manipulated visually over time but other the that I would only suspect poor GUI design.</p>

<p>Have you come across anything or built anything that has needed it, I would love to hear.</p>

<p>Cheers. </p>]]>
    </content>
    <published>2008-03-05T21:02:14Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015669</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015669" />
    <title>Comment from Radoslav Stankov on 2008-03-05</title>
    <author>
        <name>Radoslav Stankov</name>
        <uri>http://www.pixeldepo.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.pixeldepo.com">
        <![CDATA[<p>Great article. </p>

<p>p.s. I have some proposal for the blog: can you please add some code syntax highlight, because now is hard for reading.</p>]]>
    </content>
    <published>2008-03-05T21:22:22Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015670</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015670" />
    <title>Comment from Andrew Trice on 2008-03-05</title>
    <author>
        <name>Andrew Trice</name>
        <uri>http://www.tricedesigns.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.tricedesigns.com">
        <![CDATA[<p>Sorry about that.  I think we're evaluating plugins to use for the code syntax.   I agree that it can be hard to read, and I'm looking for a better solution.  If you look at the source link, it is much easier to read.</p>]]>
    </content>
    <published>2008-03-05T21:25:41Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015671</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015671" />
    <title>Comment from Andrew Trice on 2008-03-05</title>
    <author>
        <name>Andrew Trice</name>
        <uri>http://www.tricedesigns.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.tricedesigns.com">
        <![CDATA[<p>Rhys,<br />
Yes I have used this approach in several live applications.   I typically only use this approach for projects that perform heavy data visualizations, and change rapidly (and are usually tied to real-time-messaging).   They do not necessarily update as rapidly as this example, however, in theory they could.   The applications were built to handle anything that could be thrown at them, so every measure to increase performance was taken.    In one case in particular, it drastically increased performance b/c objects in the visualization were changing colors and moving across the screen at the same time.  Removing the overhead of the constructors made the transitions smoother.</p>]]>
    </content>
    <published>2008-03-05T21:35:41Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015679</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015679" />
    <title>Comment from Rich Tretola on 2008-03-06</title>
    <author>
        <name>Rich Tretola</name>
        <uri>http://blog.everythingflex.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://blog.everythingflex.com">
        <![CDATA[<p>Note from the Community Manager: Code coloring is coming very soon.</p>]]>
    </content>
    <published>2008-03-06T09:58:16Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2015689</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2015689" />
    <title>Comment from kathryn on 2008-03-06</title>
    <author>
        <name>kathryn</name>
        <uri>http://kathrynrotondo.com/blog</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://kathrynrotondo.com/blog">
        <![CDATA[<p>Really interesting article!  Looking forward to trying this out in my own code.</p>

<p>There is a typo though. The peak memory you quote for the non-cached app is missing a digit -- 1968120 should be 196812<b>8</b>0.  The typo makes it look like the non-cached version uses less memory than the cached version.</p>]]>
    </content>
    <published>2008-03-06T15:02:14Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2016808</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2016808" />
    <title>Comment from funkyboy on 2008-04-28</title>
    <author>
        <name>funkyboy</name>
        <uri>http://spreadingfunkyness.com/posty</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://spreadingfunkyness.com/posty">
        <![CDATA[<p>Hi,</p>

<p>nice post. I adopted your solution in my desktop application. I think it is the only way to save some memory, which has a "growing tendency" on Flex/Air :)<br />
So, waiting for more controllable garbage collection, thanks for your solution!</p>]]>
    </content>
    <published>2008-04-28T11:45:06Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2018917</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2018917" />
    <title>Comment from addisu on 2008-07-16</title>
    <author>
        <name>addisu</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>This is really wonderful.  I was looking for something like this because my application actually adds and removes a lot of children constantly.  There was a big different between my cached and uncached versions.  Thanks a lot.</p>]]>
    </content>
    <published>2008-07-16T23:54:31Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2018920</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2018920" />
    <title>Comment from Andrew Trice on 2008-07-16</title>
    <author>
        <name>Andrew Trice</name>
        <uri>http://www.tricedesigns.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.tricedesigns.com">
        <![CDATA[<p>Glad I could help!</p>]]>
    </content>
    <published>2008-07-17T00:32:52Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2054169</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2054169" />
    <title>Comment from Ranga Phani Kumar on 2009-02-26</title>
    <author>
        <name>Ranga Phani Kumar</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Hey Champ,</p>

<p>Great Post, I am Building a quite complex application that  Displays hell lot of UI-Components to the user. I will try to implement the concept in my application and will post the results over here.</p>

<p>Wish me Good Luck!!</p>]]>
    </content>
    <published>2009-02-27T04:07:48Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2054183</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2054183" />
    <title>Comment from Ranga Phani Kumar on 2009-02-27</title>
    <author>
        <name>Ranga Phani Kumar</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>It Does Wonders !! :-) Believe me... I create two different Display Components Obj1, Obj2 during run-time. Total instances of Obj1 are 50, instances of Obj2 are varying with requirement and might go up to 400. These are to be removed and created when ever these is a change in user filter criteria. The time take for the complete transition was 9sec. earlier, which this implementation it is down to 4 sec. </p>

<p>Thanks a lot for sharing the idea</p>]]>
    </content>
    <published>2009-02-27T08:35:49Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23037-comment:2078893</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23037" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/flex-performance-memory-manage.html#comment-2078893" />
    <title>Comment from Mitesh Dave on 2009-09-02</title>
    <author>
        <name>Mitesh Dave</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Hi,<br />
The post over here is really helpful and it really work wonders ,But i have a question,will this technique help me in memory management for module?,as you know the unloading of module doesn't remove the module from memory.It just unloads the module from display list .Any suggestions or Idea on memory management for module will be helpful.</p>]]>
    </content>
    <published>2009-09-02T07:19:57Z</published>
  </entry>

</feed
