Home >
When building applications, in most situations you'll be dealing with all sorts of dynamic content. Meaning, requesting data from a server, then displaying results on the screen by attaching objects to the display list. Usually, this means dealing with some sort of looping technique to parse the results and display them properly. For this write-up, let's assume you're attaching objects to the stage dynamically to display your results. Over time, as data is added, removed, then added again you'll see the memory consumption of the application increasing. At a certain point, these will be garbage collected, thus removing it from the memory, but this isn't the most reliable solution to keeping your application at a manageable memory level. Let's take a look at a caching technique that'll help manage this memory, and keep your application responsive after loading and unloading data. The use cases for this method doesn't rely on loading data from a server, but really pertains to constantly attaching and removing objects from the display list. Note that all example files are included in a rar file (another form of zip) at the end of this post.
Let's take a look at an example that attaches a random number of icons to the stage each time you click Attach. It will first remove what's already in the holder, then and attach a new set. For the purpose of this write-up, click "Attach" a bunch of times and you'll see the memory usage fluctuate each time it removes and adds new objects.
If you went ahead and clicked Attach a bunch of times, you probably noticed the memory going up a few megs then dipping back down, wash and repeat. The only reason it jumps back down is Flash Player's garbage collection, which makes passes through to clean up when it feels like. This isn't the most ideal situation obviously. You want to be in control of your applications memory, and these jumps can be significantly higher when attaching more than a 48x48 png. What we want to do is cache these newly created objects so we can re-use the ones we already created. Let's look at the example with the caching technique in place and compare the memory usage when hitting Attach a bunch of times. You should see the memory stay the same, maybe fluctuating a meg depending on how crazy Math.random() feels like getting. :)
Okay, you should have noticed a difference there. Clicking attach doesn't affect the memory like in the previous example that has no caching system in place. Let's check out the code now.
package com.dz.utils{
public class Cacher extends Object {
private static var cache:Array = new Array();
public function Cacher() {
super();
for (var x : Number = 0; x < 200; x ++) {
cache.push( new DTIcon() );
}
}
public static function getCached():DTIcon {
var obj:DTIcon;
if (cache.length <= 0) {
obj = new DTIcon();
} else {
obj=cache.pop() as DTIcon;
}
return obj;
}
public static function setCached(obj:DTIcon):void {
cache.push(obj);
}
}
}
Above is the actual caching class, pretty simple huh? For such a simple class, it can really be the difference between a totally unusable application and super responsive application. First, we create a new Array to hold our content that's being added to the stage. In the constructor, we populate the cache array with a minimal amount of "DTIcon" just so we have some ammo to throw at the loop when it begins. If you don't do this you'll see the memory spike the first time your loop runs since it needs to create those "DTIcon", and not use the already created ones. Keep in mind, this class doesn't need to be instantiated. So, we start with our static function to get a DTIcon when we need one. First, it's going to check if the cache array empty, and if it is, it needs to create a new instance of the "DTIcon" to satisfy the request. If the cache array isn't empty, it's going to take the last item in the array out of the array to use instead of creating a new instance. After that, the instance is returned. The next static function is used to cache an instance, or rather, store it in the cache array for later use. When you're removing the item from the stage, you'll first want to cache it so you can use it again later. That's all there is to the caching class, so let's see how to use it in an application by taking a look at the above example's code.
private function attachObjects(e:MouseEvent):void {
while (holder.numChildren) {
Cacher.setCached(DTIcon(holder.getChildAt(0)));
holder.removeChildAt(0);
}
for (var i:uint = 0; i < Math.floor(Math.random() * 10000); i++) {
ico=Cacher.getCached();
ico.x=26+i%100*5;
ico.y=60+Math.floor(i/100)*52;
holder.addChild(ico);
}
}
Above is the function that attaches the actual objects to the stage. First, we run a while loop that basically says, as long as holder has children, do this. What we do is call our static function to cache the object that is about to be removed, then we remove it. What this does is populate our cache array with more objects to use later. Then, we randomly attach some new icons, but instead of creating new instances every time, we first ask for a cached version by calling our static getCached function. If you remember, this will either return a brand new instance, or a cached instanced depending on if there is a cached instance available. Then we add it to the stage. That's it.
As you can see, with the use of this super simple class, you can really help performance in any application. You will see a much larger performance gain when dealing with a large scale application that creates new instances of the same object repeatedly. I shaved about 10mb off DeskTube by implementing this caching system. Not only did I shave them off, but it made the application more stable by keeping the memory usage more consistent.
Thanks for reading!
Example files:
Caching.rar



Facebook Application Development
That is the solution I adopted as well.
http://spreadingfunkyness.com/garbage-collection-with-flex-and-adobe-air/
Hope in the future Adobe will solve this problem within the Flash Player.
Hey cool, great minds think alike!
I've done some work on keeping the classes that load your data, clean:
http://blog.pietergrobler.com/node/4
In combination with your solution, it could get closer to a comprehensive memory management kit, taking care of all three domains in the MVC framework.
Hi,
It is such a useful article and I found a lot of information with the help of this article. Thank you so much for sharing.
Stella
homes for sale