Garbage Collection in the UcompOS RPF

OscarTheGrouch In large and sophisticated Flash-based applications, such as the Rich Portal Applications you develop with the UcompOS Rich Productivity Framework, Garbage Collection becomes an increasingly important consideration.

Garbage Collection is a computer science concept that deals with memory management and re-allocating memory occupied by objects that are no longer needed or in use by the computer program.

Garbage Collection in a large-scale event-driven Flash architecture is a crucial consideration and unfortunately, can also be a tedious proposition to properly implement.

One of the more important considerations in aiding with Garbage Collection in Flash-based application is proper management of event listeners.

In a best-practice implementation, any call to addEventListener() would be followed up with a call to removeEventListener() once the event listener was no longer needed. Event listeners perpetuate the objects they are associated with so even once a particular object is destroyed, that doesn’t necessarily mean any event listeners associated with it will be destroyed too.

Failure to remove event listeners once they are no longer needed in a large-scale implementation can cause memory leaks and performance can break down over time.

In all your Flash applications, you should employ this strategy when and where possible.

In a typical large-scale UcompOS RPF implementation, Flash-based applications and sub-applications are continuously being loaded and unloaded into the UcompOS Portal.

The concept of Proxy Components in the UcompOS RPF involves event listeners being attached to a Proxy Component in one entity that represents an object in another UcompOS entity and then listening for dispatched events.

Therefore, the concept of garbage collection takes on especially critical importance in the UcompOS RPF because if UcompOS applications are being loaded and unloaded constantly and the event listeners that are attached to them are not being properly removed, performance would become an issue in a large-scale implementation.

The UcompOS Portal has been designed such that when SWF content that has been loaded into the UcompOS Portal is unloaded, a garbage collection routine is implemented to try to optimize system performance. (The three ways SWF content is loaded into the UcompOS Portal is in UcompOS Window instances, UcompOS Artifact instances, or into the UcompOS run-time.)

As of the UcompOS RPF Public Alpha release 0.4.6, some additional enhancements to the garbage collection process have been implemented that I will discuss here.

Understanding the UcompOS RPF garbage collection architecture can help you build more scalable Rich Portal Applications.

The recent enhancements come in the realm of Proxy Components.

By strict convention, all Proxy Components must extend the SDK class AbstractProxyComponent. As of UcompOS RPF 0.4.6, AbstractProxyComponent now extends a new SDK class called SDKEventDispatcher which extends EventDispatcher.

(Also, as a side-note, the AbstractProxyComponent class now implements IEventDispatcher in addition to IProxyComponent so you can refer to your Proxy Components as IEventDispatcher or IProxyComponent instances interchangably.)

SDKEventDispatcher simply overrides addEventListener() and offers a protected property _listeners of type Array.

I chose to create this separate class versus simply overriding addEventListener() in AbstractProxyComponent so that in the event the new clean-up process employed can be useful outside the scope of a Proxy Component, one could simply extend SDKEventDispatcher versus EventDispatcher.

Here is the over-ridden addEventListener():

override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
	_listeners.push({type:type,listener:listener});
	super.addEventListener(type,listener,useCapture,priority,true);
}

Notice that I am always assigning a true value to the useWeakReference parameter in the super call to addEventListener(). This is because in the context of attaching event listeners to Proxy Components, you always would want them to be weak references to aid in garbage collection.

In AbstractProxyComponent, there is a new protected method, cleanup() which is as follows:

protected function cleanup(event:SDKEvent=null):void
{
	while(_listeners.length)
	{
		var object:Object = _listeners.pop();
		removeEventListener(object.type,object.listener);
	}
	_sdkModel.removeProxyComponent(this.uuid);
	var commandObject:CommandObject = new CommandObject("SDK.cleanup",{uuid:this.uuid});
	var dataPackage:DataPackage = new DataPackage(Utilities.createUID(),_sdkModel.connectionId,this.destination,commandObject);
	_sdkClient.send(dataPackage);
}

What the cleanup() method does is it automatically removes any event listeners that have been attached to the Proxy Component.

It also sends a message to the end-point of the Proxy Component targeting its SDK.cleanup public API method that is built into the UcompOS SDK and therefore exposed by any UcompOS entity. This aids in UcompOS RPF garbage collection-related activities.

Calls to cleanup() do not occur automatically.

When you would call cleanup() in a Proxy Component would be an implementation specific consideration.

For instance, with these new capabilities, I have updated some of the UcompOS Portal Proxy Components that are built into the UcompOS SDK.

Consider the updated constructor of the UcompOSWindowProxy class:

public function UcompOSWindowProxy()
{
	super();
 
	// set the destination property to the UcompOS Portal
	super._destination = _sdkModel.root;
	<strong>addEventListener(CLOSE,cleanup);</strong>
}

The call to addEventListener(CLOSE,cleanup) is the new addition to the constructor.

What it does is it causes the inherited cleanup() method to always be called when the UcompOS Window instance on the UcompOS Portal that is represented by the UcompOSWindowProxy instance is closed.

Therefore, any event listeners you have attached to the UcompOSWindowProxy instance are automatically removed whenever the window is closed.

In 100% of the possible use cases for the UcompOSWindowProxy, this is the desired behavior.

The net result of this is you don’t have to worry about making your own calls to removeEventListener() for your particular UcompOSWindowProxy instances.

The same sort of behavior has been engineered into some of the other Proxy Components built into the UcompOS SDK including UcompOSAlertProxy, UcompOSDialogueProxy, UcompOSArtifactProxy, and UcompOSBrowserWindowProxy.

Consider this strategy when you are building your own Proxy Components and remember to always use removeEventListener() in all your other Flash applications whether you are deploying them in the UcompOS Portal or not.