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.

Meet the UcompOS Portal Proxy Components

If you’ve read my previous postings, you should now have a basic understanding of some of the core mechanics of the UcompOS Rich Productivity Framework including Proxy Components and Services Dictionaries.

The concept of the UcompOS Continuum should also be somewhat clearer now as well as the roles of the UcompOS Portal and the UcompOS SDK in the context of the UcompOS Continuum.

Despite the obvious significance of the UcompOS Portal, in the context of the UcompOS Continuum, it is just another entity with the UcompOS SDK implemented that publishes a Services Dictionary of public API methods exposed for other entities.

To take advantage of this fact, the UcompOS SDK has a host of Proxy Components built into it that can be thought of as client interfaces to the public API methods exposed by the UcompOS Portal.

Understanding the mechanics of building your own UcompOS public API methods and Proxy Components to those public API methods is the key to unleashing the true power of the UcompOS RPF and creating the most compelling rich experiences for users of your Rich Portal Application.

But even a basic exploration of the SDK’s built-in UcompOS Portal Proxy Components is a fun way to explore and learn.

In this post, I’ll introduce you briefly to the UcompOS Portal Proxy Components.  I won’t spend a lot of time detailing them as you’ll likely see some dedicated blog postings from me covering the individual Proxy Components and their nuances in the coming weeks.

Each Proxy Component covered is built into all 3 UcompOS SDKs – AIR, Flex/Flash, and JavaScript.

The implementation details of using the AIR and Flash/Flex (ActionScript 3.0) Proxy Components versus the JavaScript Proxy Components are very subtle and of course full SDK documentation is online for the ActionScript 3.0 SDK as well as the JavaScript SDK.

Since the SDK documentation is online, I won’t spend a lot of time covering the methods, properties, and events of the Proxy Components (as you can get all this information in the docs), rather I’ll just give a first-person synopsis of what you can do with each of the Proxy Components.

UcompOSAIRProxy

The UcompOSAIRProxy class allows you to create a virtual representation of a UcompOS AIR application in an entity.  Once you create this virtual representation, you then use this class’s launchApplication(); and quitApplication(); method to control the start and stop of the AIR application.  Then any communication with the AIR application is handled via the traditional means of Proxy Components and public API methods.  The UcompOSAIRProxy class would be used when you wanted to launch a UcompOS AIR application as a sub-application.  If the UcompOS AIR application was to be a base application, you would just have the network URL to the air package in the application manifest and the AIR application would be launchable from the UcompOS application dock.  See my tutorial entitled A Simple HTML Digital Camera Browser for an example of this.

UcompOSArtifactContainerProxy

The UcompOSArtifactContainerProxy class lets you create a container for UcompOS Artifacts on the UcompOS Portal.  A UcompOS Artifact is essentially a “widget” that can be an image or SWF application that can have functionality attached to it (drag and drop, double click, click, rollover, context menu, etc.).

A UcompOS Artifact Container then is a visual layout container for these artifacts.  I gave an example of this in my tutorial entitled Building a UcompOS Weather Channel Widget.

An example may be a taskbar.  Suppose I want to layout a number of widgets each with its own specific functionality attached to it along the bottom right corner of my UcompOS Portal interface.

To do this I could create a UcompOS Artifact Container via the UcompOSArtifactContainerProxy class.  Then when I create my UcompOS Artifact, I would pass a reference to my UcompOSArtifactContainerProxy instance and the artifact would be placed into the relevant container.

There are 3 layout options at present with the UcompOS Artifact Container: HBox, VBox, and Tile

These are parallel to the classes of the same name in the mx.containers package from the Flex 3 framework (FYI the UcompOS Portal is built on Flex 4).

UcompOSArtifactProxy

The UcompOSArtifactProxy is a class used to create UcompOS Artifacts on the UcompOS Portal.

A UcompOS Artifact can be thought of as a widget.  The widget can be purely presentational, or it can have functionality attached to it as my Weather Channel Widget example demonstrated.

The visual content of a UcompOS Artifact can articulated as one of three forms:

  1. The network URL to an image (PNG, GIF, JPG)
  2. The network URL to a SWF appication
  3. A ByteArray representation of an image

You then attach functionality to a UcompOS Artifact by calling the UcompOSArtifactProxy‘s many public methods and attaching various event listeners to it to handle click, double click, rollover, rollout, drag and drop, and other various events.

If the visual content of your artifact is a SWF, this SWF can be a UcompOS sub-application for even more exciting interactive possibilities.

At this point, HTML-type applications cannot be used as artifacts

As described above in my discussion of the UcompOSArtifactContainerProxy class, you can add a UcompOS Artifact to a container so that groups of similar artifacts can be arranged together in a logical presentation.

One cool thing you can do, if you don’t add an artifact to a container and just position it at specified coordinates on the UcompOS Portal, you can make it draggable.  And because you can configure artifacts to accept drops, the ability to drag and drop one artifact to another to create some desired behavior or functionality exists.

I’ll likely devote a tutorial to this interesting capability in the near future.

UcompOSBrowserWindowProxy

The UcompOSBrowserWindowProxy class lets you launch a satellite browser window from the UcompOS Portal.  You can add generic content to the browser window, or you can load a UcompOS sub-application.

The ability to communicate with a UcompOS sub-application loaded in a satellite browser window is the exact same as if the sub-application was loaded in the UcompOS Portal run-time, in a UcompOS Window, or in a UcompOS Artifact.

UcompOSDockProxy

The UcompOSDockProxy class lets you exert control over the UcompOS Portal’s Application Dock.

You can do things such as set context menus to the application icon an entity is associated with.  You can also change the size of the icons on the dock as well as control the “genie” effect (the effect where the dock icons expand and then contract as the mouse passes over them).

You can also hide the dock completely using the showDock(visible:Boolean):void; method.

And one of the more important capabilities is you can set an alert for the icon on the dock an entity is associated with using the setAlert(); method.  This would be useful perhaps in e-mail or instant messaging applications to alert the user of receipt of a new e-mail or instant message.

UcompOSGlobalManagerProxy

The UcompOSGlobalManagerProxy class provides an interface to a number of important visual and data features  of the UcompOS Portal.

For instance, if you wanted the UcompOS Portal to throw a generic Flex-style Alert, you could use the createAlert(); method.

If you wanted to dispatch an event to all entities in the UcompOS Continuum, you could use the dispatchContinuumEvent(); method.

Suppose you wanted to launch another UcompOS application from within an entity.  You could call the launchApplication(); method and pass the manifest URL of the target application’s application manifest.

These are only a few of the important duties the UcompOSGlobalManagerProxy facilitates.

UcompOSHTMLProxy

The UcompOS Portal is a Flex 4 application embedded in an HTML wrapper.

The UcompOSHTMLProxy class lets you call JavaScript functions in the HTML wrapper.

The class provides the alert();, confirm(); and prompt(); methods which invoke the JavaScript functionality of the same name.

You can then add event listeners such as UcompOSHTMLProxy.CONFIRM_SUBMIT and UcompOSHTMLProxy.PROMPT_SUBMIT to capture user-input.

You can also use the javascript(); method to pass pure JavaScript code.

So one possibility here, in the ucompos/local/LocalLib.js JavaScript file in the UcompOS Developers Package that you customize to create your own authentication, you can implement your own JavaScript methods that perform specific tasks and then access these methods from the UcompOSHTMLProxy.

UcompOSMenuBarProxy

The UcompOSMenuBarProxy lets you set the dataProvider for the UcompOS Menu Bar and your particular menu bar implementation comes into view when the UcompOS application associated with the entity that set the menu bar model comes into focus.

You can even associated a menu bar model with an individual UcompOS Window instance.

You then attach event listeners to capture user menu selections.

Two cool random quick points is that you can pass a baseMenu=true value to the second parameter of the setMenuBar(); method and it will remove the default UcompOS menu bar item so you can 100% customize the menu.  Also, in your dataProvider to the menu you can attach an icon property with the network URL of images you want to use for the individual menu bar nodes.

UcompOSStyleProxy

The UcompOSStyleProxy class lets you take control over the portal’s visual presentation including the background image (wallpaper) that appears on the UcompOS portal.

With the setTheme(); method, you can set the MDI window theme to one of 3 different pre-existing window themes.  Right now, I just have the 3 that come packaged with the flexlib.mdi package implemented (Windows XP, Mac OS 9, and the default style) but it is my intention to expand this.

There is also a setEffects(); method that let you control the visual effects that occur when UcompOS Windows are closed or minimized/maximized.  The options are Default, Linear, and Vista which are the effects built into the flexlib.mdi package.

There is also a generic setStyle(); method that lets you set a generic CSS style property to the UcompOS Portal.

One important point about this method.  When you call setStyle();, the UcompOS Portal dispatches a UcompOS Continuum Event – meaning that all entities get notified about the style change.

So if you did something like this:

UcompOSStyleProxy.getInstance().setStyle("Button","color",0xFF0000);

Every entity would be notified that the Button selector’s color property was just given a red value on the UcompOS Portal.

You could then listen for this UcompOSStyleProxy.STYLE_CHANGE event and change the visual presentation of an entity’s internal controls accordingly.

UcompOSWindowProxy

The UcompOSWindowProxy class is used to create MDI window instances on the UcompOS Portal and then load generic web content or a UcompOS sub-application into them.

The class documentation is definitely worth a look as there are a lot of really cool features you can employ with UcompOS Window instances.

So that’s it.  A brief look at all the UcompOS Portal Proxy Components built into the UcompOS SDK.

I invite you to view the source code of the the JavaScript SDK and you can check the UcompOS Flash/Flex SDK written in ActionScript 3 out of the UcompOS SVN Repository.  Viewing this code will give you some better ideas of how to construct Proxy Components.

I have not yet made the source code of the UcompOS Portal publicly viewable and do not have a timeline for doing so but if you have questions about how I have built the public API methods on the UcompOS Portal, please bring questions to me in the UcompOS Forum and I’ll share relevant strategies and code examples.