Skip to content
September 16, 2010 / jetspiceflex

HTML and XML Garbage Collection in Adobe AIR

Let’s say you want to build an RSS reader in AIR, and you need full HTML support to display the feed. Your reader might switch between a few feeds so you are also loading the XML dynamically.

You’ll notice two things:

  • As the app runs, your memory usage keeps growing and growing.
  • Some RSS entries are too big to be displayed entirely.

This is because:

  • XML is not being garbage collected.
  • The HTML component’s height can only be 2880. (or 4096 in AIR2)

A solution for the HTML height limitation challenge is to dynamically populate a container with multiple HTML components using actionScript (like, in a VBox).

The XML that I was using had a tag which contained HTML. I was fortunate enough to be able to parse the HTML-inside-the-XML and divide it into several chunks by using “<br/>” as a delimiter:

private function createHTML():void
{
	//rss is the XML from the feed
	//currentItem is the current entry within the feed being displayed
	var content:String = String(rss.item[currentItem].content);
	//by putting the delimiter in parenthesis ( ), it is appended to the array
	var array:Array = content.split(/()/);
	var html:HTML;

	for (var i:uint; i < array.length; i ++)
	{
		html = new HTML();
		html.width = this.width;
		html.htmlText = array[i];
		this.addChild(html);
	}
}

When you change the XML feed or change currentItem, you’ll need to remove the the HTML components (firstly setting their content to null), and also the XML feed. Thanks to Greg Wilson’s Ramblings on garbage collection.

private function clearHTML():void
{
	var html:HTML;
	for (var i:uint; i < this.numChildren; i++)
	{
		if (this.getChildAt(i) is HTML)
		{
			html = HTML(this.getChildAt(i));
			html.htmlText = ""; //set the content to null
		}
	}
	this.removeAllChildren();
}

Before loading any other xml feeds, do this first:

System.disposeXML(rss);

I don’t advise passing the XML down to nested components, because of the way AIR prepares XML for garbage collection (as in, it doesn’t).
Instead, convert what you need to a string or array or arrayCollection, and pass that down to nested components. I do this right away and System.disposeXML(rss) immediately afterwards. For this same reason, I would avoid binding for a project like this. MXML and binding are super fast ways to develop, but in this case, the garbage collection is a bigger issue.

After all that, if the app’s memory usage still grows, you can follow Sean Christmann’s advice (from Craftymind)  here.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: