Thursday, May 28, 2009

Flex Memory Issue #3: Garbage Collection

Garbage collection is an in depth subject when it comes to modern programming languages. Wikipedia provides a general statement that summarizes what it is:

“…garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory used by objects that will never be accessed or mutated again by the application.“ http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

The expectation of a programmer in a language like Flex or Java, is that when widget X is no longer being used in the application that it gets removed from memory. That it is pretty simple scenario that is unrealistic, considering all graphical user interface components maintain references to other components which contain references to other components and so on and so forth. Flex also adds a few more layers of complexity by including modules and binding.

Flash Garbage Collection Basics

There is a must-read presentation on an atomic view of Flash Player garbage collection written by Alex Harui sometime in 2005, from which I obtained a lot of my high level information. Somehow I located the presentation through the internet and downloaded it, but I have since lost the link.

Flex garbage collection is synonymous with Flash garbage collection, since the memory being talked about is that of the Flash Player. Flash memory allocation basically works by grabbing chunks of memory from the Operating System, and carving those chunks when needed into smaller blocks of fixed size that together as a group are called a pool. When a pool is used up then another chunk is taken from the OS and becomes another pool.

A block of memory can be used, freed, or unused. Used means that there is something in there, freed means that something is still in there but it no longer used and can be garbage collected, and unused means that the block was freed and had been set to unused by the garbage collector.

clip_image002

This means that Flash garbage collection is based on allocation since more memory is not obtained from the OS until Flash needs some for itself but is out. Before Flash decides that another pool is needed though, it might attempt to run garbage collection. The garbage collector will move through Flash memory looking for freed blocks that can be set to unused.

There are also a few important things to note about garbage collection when looking at its effect on memory:

1. You generally can’t predict when garbage collection will run by itself

2. Garbage collection is based on allocation, so memory will remain constant in an idle application

3. Garbage collection is not guaranteed to mark all the blocks is can as unused in one pass, which means that memory may never returned to its initial point

For a more details about the Flash garbage collector Grant Skinners has several writings about it in his AS Resource Management series: http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

So why do I care about garbage collection?

It doesn’t always collect what you want it to when you want it to, and when dealing especially with modules it can lead to some behaviors that look like memory leaks. I have personally found that if you want to get memory under control with modules you absolutely have to force garbage collection. For example consider a test application in which I am loading and unloading the same three modules over an over again into the current application domain. I know, what is an application domain? For now don’t worry about because it is complicated and something that I intend to explain later in another article. All you need to be aware of that this is the default module behavior if you use the Module Manager to load a module without using any parameters.

image

Without getting into the details of application domains and their specific effects on memory behavior, you can at least see that if you don’t force garbage collection memory just keeps going up with little breaks in between. In the case of the application that I am describing it will eventually cause my browser to run out of memory and lock up once the Flash Player gets upwards of 120 MB. 

I have also found that the larger the modules and the more detailed the styles the more pronounced this problem. I believe that when I averaged out the increase in memory over time,  it ended up being about 1.5 MB per module load. If you force garbage collection after each module unload it ends up being pretty much a flat line, granted though other techniques were incorporated in this application to help memory along to be discussed in future articles. The important thing to note is the positive effect forced garbage collection has by itself.

Force garbage collection?

Junior Java programmers love to ask the question about how to force garbage collection, to which the reply is always that you can only suggest it. The same is not true for Flex, as there are unsupported techniques that have various effects in the debug and non-debug Flash Player as well as with AIR.

Method 1: System.gc()

According to the Adobe documentation (http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html) this forces garbage collection, but only in AIR and the debug version of the Flash Player. In practice though this method doesn’t seem to be very effective for reasons listed below.

Method 2: System.gc() twice in a row

According to Sean Christmann’s post about kick starting the garbage collector (http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/), if you call System.gc() twice in a row it is far more effective. Unfortunately though this only works in the debug Flash Player and AIR.

Method 3: The local connection hack

According to Grant Skinner’s third installment of this AS Resource Management Series (http://www.gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html), you can force garbage collection by calling two local connections in a row:

try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}

In testing this I find that it works in AIR, the debug Flash Player, and the non-debug Flash Player. It is also the my preferred way of forcing garbage collection, even though it it not supported.

When do I force garbage collection?

I have engaged in several debates regarding when to force garbage collection and why, and the most important thing you need to understand is that forcing garbage collection will only clear objects that are eligible for collection in the first place. This means that if you write a loop in your application to force garbage collection at 70 MB until it goes down to 50 MB you are probably going to loop infinitely. Forcing garbage collection is not the silver bullet to all of your memory problems.

When to force garbage collection really depends on what your application is doing. For example if your application just consists of several screens you might try forcing garbage collection in between screens. In other applications it may be more appropriate to force it every few minutes.

How do I make objects eligible for garbage collection?

Now that is the million dollar question, and unfortunately there is no one answer. The purpose of this series on Flex memory issues is designed to help one thing at a time. Binding, states, modules, effects, application domains, complex components, listeners, and more will have their memory issues explained.

Wednesday, May 27, 2009

Flex Memory Issue #2: Component effects cause leaks

An effect is a change to a component that occurs over a brief period of time (http://www.adobe.com/devnet/flex/quickstart/adding_effects/). Flex provides a series of predefined effects which you can be played individually, simultaneously, and one after another as a group. They are useful for adding that “wow” factor to your application by giving it animation. There is a problem though with using these effects, which is that if you remove a component that has had an effect played on it that component will still reside in memory until another effect is played.

This is because all effects are controlled through the EffectManager, which keeps track of the last effect played through the “lastCreatedEffect” property. This may not seem like a big deal since it will just change when you play another effect, but is a big deal of you are limited on the amount of memory you can use and the component being held onto is large. It is also an annoyance if you are trying to track down leaks and components that shouldn’t be there because of this are floating around in memory.

The solution to this problem is pretty simple, which is to just call EffectManager.lastCreatedEffect = null when you are done with your effect. After figuring this out on my own I Googled around and was able to find that someone created a defect for it back in 2008.

Component effects via EffectManager cause memory leak (http://bugs.adobe.com/jira/browse/SDK-18061)

Steps to reproduce:
1. Create an MXML component with an effect, e.g.
  <mx:HBox id="myBox" resizeEffect="{new Resize()}"/>
2. Use the component such that the effect gets played, e.g. set its size explicitly in this case
3. Remove the component.

Actual Results: the component is not garbage collected.

Expected Results: the component is garbage colloected.

Workaround (if any): Explicitly register an EFFECT_START listener on the effect to set EffectManager.lastCreatedEffect = null when the effect plays.

This leak occurs because lastCreatedEffect is a static variable and thus hangs on the the last played effect, which then hangs on to its target component, etc. I recommend removing this static field completely. If it is really needed, make it a weak reference instead.

Tuesday, May 26, 2009

Flex Memory Issue #1: The debug player always leaks

In the 9 and 10 versions of the Flash Player there are both debug and non-debug versions of those players. If you are writing Flex application you most certainly have the debug version, which lets you output to trace as well as write those trace statements to a log on the local file system of you have the correct settings. There is a problem with the debug version of the Flash Player though, which is that it is full of memory leaks.

This is important if you are trying to get memory under control in a Flex application, because if you are just looking at the System.totalMemory in the debug player you are wasting your time. This problem with memory and the debug player is most evident if you are using modules, which you can see by loading modules over and over again and comparing System.totalMemory over time in the debug and non-version of the Flash Player.

Using the latest in computer modeling technology the result looks like the following:

image

This means that if you want to get a realistic picture of memory behavior using System.totalMemory, or by looking at the effect on the containing browser or AIR executable, you have to use the non-debug version of the Flash Player. The debug version of the Flash Player is still useful for looking at memory usage though, but you have to use the profiler.

image

The profiler memory usage panel displays the amount of memory used by object allocation, and will not correlate with System.totalMemory. How do I know this? Well, I took the time to add up all of the objects listed in Live Objects panel and it always adds up to the amount listed for Current Memory. Overtime System.totalMemory will further diverge from the displayed Current Memory, because the actual memory used will continue to grow because you are using the debug player.

image

I was never able to find a good explanation of the huge difference between Current Memory and the actual memory consumed by the application when running with the profiler versus the non-debug version of the Flash Player, but I have also found that the memory usage overtime of an application in the profiler according to Current Memory will roughly match the memory usage of that same application overtime run using the non-debug version of the Flash Player. It is a rough match because there is of course other stuff in memory than just object allocations.

image

The non-debug version of the Flash Player is good for locating a generic problem with memory at the level of “hey, this little application started at 30 MB and is now at 300 MB,” while the profiler is good for narrowing down which instances are leaking. When investigating memory in Flex applications you just have to be aware of how whether you are using the debug or non-debug version of the Flash Player effects your results.

Flex: event.target versus event.currentTarget

The event system in Flex allows you catch an Event and its instance to get reference to the component that generated the event.

For example if you do make the following declaration in MXML:

<mx:Button click=”clicked(event)” />

When that button is clicked it calls in ActionScript the function “clicked(event:MouseEvent):void”

So how do you get reference to the button that generated the event in that function?

Well, according to the Adobe Event API (http://livedocs.adobe.com/flex/3/langref/flash/events/Event.html) you can use:

  • event.target - The event target. This property contains the target node. For example, if a user clicks an OK button, the target node is the display list node containing that button.
  • event.currentTarget - The object that is actively processing the Event object with an event listener. For example, if a user clicks an OK button, the current target could be the node containing that button or one of its ancestors that has registered an event listener for that event.

So what does that mean and which should I use?

You can’t tell from that description, but I can tell you about a problem I was having with a component displaying lots of buttons. So there was a component with lots of buttons on it, where when a button was pressed it would call a function that would determine which button was pressed and do all sorts of fancy stuff.

image

The callback function looked something like the following:

private function clicked(event:MouseEvent):void

{

var button:button = event.target as Button;

trace(button.label);

}

The problem with this was that if the user started clicking on buttons really fast a null pointer exception would occur, because the “button” instance was null. After debugging this I realized that the button was null because for a few cases when the button was clicked the event.target was a UITextField, what?

That is when a stumbled onto some more event documentation currently located at http://livedocs.adobe.com/flex/3/html/help.html?content=16_Event_handling_5.html:

The target property

The target property holds a reference to the object that is the target of the event. In some cases, this is straightforward, such as when a microphone becomes active, the target of the event object is the Microphone object. If the target is on the display list, however, the display list hierarchy must be taken into account. For example, if a user inputs a mouse click on a point that includes overlapping display list objects, Flash Player and AIR always choose the object that is farthest away from the Stage as the event target.

For complex SWF files, especially those in which buttons are routinely decorated with smaller child objects, the target property may not be used frequently because it will often point to a button's child object instead of the button. In these situations, the common practice is to add event listeners to the button and use the currentTarget property because it points to the button, whereas the target property may point to a child of the button.

The currentTarget property

The currentTarget property contains a reference to the object that is currently processing the event object. Although it may seem odd not to know which node is currently processing the event object that you are examining, keep in mind that you can add a listener function to any display object in that event object's event flow, and the listener function can be placed in any location. Moreover, the same listener function can be added to different display objects. As a project increases in size and complexity, the currentTarget property becomes more and more useful.

Pay attention to the following statement in the section about the target property:

“…common practice is to add event listeners to the button and use the currentTarget property because it points to the button, whereas the target property may point to a child of the button.”

So after reading this I changed my code to use event.currentTarget from event.target, and it always returned the instance of the button that was clicked.

I also found another article (http://mysticnomad.wordpress.com/2008/03/21/difference-between-eventtarget-and-eventcurrenttarget-properties-in-an-event-object/) that clearly laid out the distinction between these two properties, and made the conclusion that “…you should always use event.currentTarget property instead of event.target.”

I agree.

Sunday, May 10, 2009

Command Module Framework

What is it?

The Command Module Framework is a series of classes for working with modules in Flex, which extends the default module behavior to compensate for numerous known problems as well as to add needed functionality.

In particular the following is a list of some of the more important functional differences:

  • The ability to queue events on the module loader which get dispatched to the module implementation once it is loaded and ready
  • Modules when unloaded go through a series of magic tricks to help them actually unload. Some day I will get around to explaining what a lot of these tricks are and why they are needed.
  • The ability to configure a manager to handle loading and unloading modules in view stacks
  • The built in ability to share data between all modules
  • The built in ability to optionally display module loading progress
  • Makes it easier to communicate between modules

What is it intended to be used for?

This library is intended to be used for Flex applications that need to load and unload modules, with a lot of the common code used for doing this already written.

Modules are used so that the user of your application only has to download the parts they need when they need it. For example if an application is a series of 100 different forms, it makes sense that the user should only have to download the forms they intend to use. The is a big deal in web applications because is means the difference (depending on your connection speed) between spending 15 minutes downloading a large application versus spending 5 seconds downloading an application framework and 3 seconds for each additional module.

How does it work?

There are two general ways to use it:

  1. Using the Command Module Loader, which is similar to the Module Loader
  2. Using the Command Module Manager, which is similar to the Module Manager

Using the Command Module Loader (Example #1)

The Command Module Loader is very similar to the Module Loader, and can be used as in the same way in a basic example:

Application.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="
http://www.adobe.com/2006/mxml"
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*">
    <commandmodulefr:CommandModuleLoader url="valentino/modules/ModuleA.swf" />
</mx:Application>

The code for Module A is the following:

ModuleA.mxml

<?xml version="1.0" encoding="utf-8"?>
<commandmodulefr:CommandModule
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*"
    xmlns:mx="
http://www.adobe.com/2006/mxml">
    <mx:Panel title="Module A" width="100%" height="100%">
        <mx:Button label="I am a button" />
    </mx:Panel>
</commandmodulefr:CommandModule>

The result is an application that loads the module at the given URL, assuming it inherits from the CommandModule class, which in the case of this module results in a panel with a button in it:

image

Sending events to modules (Example #2)

Let’s say that for some reason you want to send an event to your module, but being a smart Flex developer you are aware of the following:

  • I can’t reference an instance of my custom module class in my main application because that would cause that class to get compiled in with my main application, which would defeat the purpose of modules
  • If I dispatch an event directly to the loader using dispatchEvent, my module could miss that event if it is not already loaded

For these reasons the CommandModuleLoader class has a queueEvent function which ensures that the module always gets the event no matter when it is dispatched.

For this example there is a button in the main application that when pressed sends some custom event to the module:

Application.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="
http://www.adobe.com/2006/mxml"
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*">
    <mx:Script>
        <![CDATA[
            private function sendSomeEvent():void
            {
                var event:Event = new Event("someCustomEvent");
                moduleLoader.queueEvent(event);
            }
        ]]>
    </mx:Script>
    <mx:Button label="Send Some Custom Event" click="sendSomeEvent()" />
    <commandmodulefr:CommandModuleLoader id="moduleLoader" url="valentino/modules/ModuleA.swf" />
</mx:Application>

In the module there is a listener created on initialization for the custom event, which when the event is dispatched displays a popup window:

ModuleA.mxml

<?xml version="1.0" encoding="utf-8"?>
<commandmodulefr:CommandModule
    initialize="onInit()"
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*"
    xmlns:mx="
http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            private function onInit():void
            {
                this.addEventListener("someCustomEvent", someHandler);
            }
            private function someHandler(event:Event):void
            {
                Alert.show("Some Custom Event!");
            }
        ]]>
    </mx:Script>
    <mx:Panel title="Module A" width="100%" height="100%">
        <mx:Button label="I am a button" />
    </mx:Panel>
</commandmodulefr:CommandModule>

image

Receiving events from modules (Example #3)

In order to receive an event from a module you must attach some listener on the actual module, and being a smart Flex developer you are aware of the following:

  • I can’t reference an instance of my custom module class in my main application because that would cause that class to get compiled in with my main application, which would defeat the purpose of modules
  • Being able to reference an event function using an attribute in the MXML of the loader would require the loader to already have the desired event metadata declarations

For these reasons the base implementation of the loader has an event for when the module is loaded, which can be caught in order to obtain a reference to the CommandModule class. This instance can then have a listener for anything you want added to it.

Application.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="
http://www.adobe.com/2006/mxml"
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*">
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import net.sourceforge.commandmodulefr.CommandModule;
            import net.sourceforge.commandmodulefr.event.CommandModuleEvent;
            private function moduleLoaded(event:CommandModuleEvent):void
            {
                var module:CommandModule = event.module;
                module.addEventListener("someCustomEvent", someHandler);
            }
            private function someHandler(event:Event):void
            {
                Alert.show("Some event from a module!");
            }
        ]]>
    </mx:Script>
    <commandmodulefr:CommandModuleLoader
        moduleLoaded="moduleLoaded(event)"
        url="valentino/modules/ModuleA.swf" />
</mx:Application>

When the button is pressed in the module, it dispatches the expected event which is then picked  up in the main application.

ModuleA.mxml

<?xml version="1.0" encoding="utf-8"?>
<commandmodulefr:CommandModule
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*"
    xmlns:mx="
http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            private function sendEvent():void
            {
                var event:Event = new Event("someCustomEvent");
                this.dispatchEvent(event);
            }
        ]]>
    </mx:Script>
    <mx:Panel title="Module A" width="100%" height="100%">
        <mx:Button label="I am a button" click="sendEvent()" />
    </mx:Panel>
</commandmodulefr:CommandModule>

The result is a window that is displayed when the button within the module is pressed.

image

Sharing data between modules and the main application (Example #4)

Besides just using a singleton, the Command Module Loader accepts an Application Context object that is passed to all of the modules that are loaded. This class contains a data attribute which is an object that can be populated with anything, or you can just extend this class and defined a shared structure.

In this example the main application declares the Application Context, and sets the data so that “someVar” has a value.

Application.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application initialize="onInit()"
    xmlns:mx="
http://www.adobe.com/2006/mxml"
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*">
    <mx:Script>
        <![CDATA[
            import net.sourceforge.commandmodulefr.data.ApplicationContext;
            [Bindable]
            private var _context:ApplicationContext = new ApplicationContext();
            private function onInit():void
            {
                _context.data.someVar = "This is some text";
            }
        ]]>
    </mx:Script>
    <commandmodulefr:CommandModuleLoader
        context="{_context}"
        url="valentino/modules/ModuleA.swf" />
</mx:Application>

The module then uses that value from the Application Context in order to get the text that it displays on the button.

ModuleA.mxml

<?xml version="1.0" encoding="utf-8"?>
<commandmodulefr:CommandModule
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*"
    xmlns:mx="
http://www.adobe.com/2006/mxml">
    <mx:Panel title="Module A" width="100%" height="100%">
        <mx:Button label="{context.data.someVar}"  />
    </mx:Panel>
</commandmodulefr:CommandModule>

The result is the following:

image

Using the Command Module Manager (Example #5)

The Command Module Manager is far more generic, and is actually intended to be used as part of some other framework in an application. The module manager class is useful for when you do not want to have to declare every module that you intended to use. An example usage would be in an application that has a list of the URL’s of all of the module that it can load in some external XML file, where various events in that application would result in modules from that XML file being loaded.

The two most notable things about the Command Module Loader class are the following:

  1. It takes a view stack as a parameter and loads and unloads module into and out of that view stack.
  2. It cleans up modules so that they can actually be unloaded (somewhat, but this is for a later lengthy discussion)

Now consider an application that just has a series of buttons for loading and unloading modules, and a general area that the modular content is displayed in using a view stack. Though this usage seems really simple, it is a quite common template for an application.

Application.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="
http://www.adobe.com/2006/mxml"
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*">
    <commandmodulefr:CommandModuleManager id="manager" viewStack="{view}" />
    <mx:Button label="Load Module A"
        click="manager.requestLoadModule('valentino/modules/ModuleA.swf')" />
    <mx:Button label="Unload Modules" click="manager.unloadAll()" />
    <mx:ViewStack id="view" />
</mx:Application>

The idea behind the module manager is to allow an application an easy way to change out dynamic content which comes from modules. The generic nature of the Command Module Manager then allows the individual application to decide about the details of how module communication occurs.

ModuleA.mxml

<?xml version="1.0" encoding="utf-8"?>
<commandmodulefr:CommandModule
    xmlns:commandmodulefr="net.sourceforge.commandmodulefr.*"
    xmlns:mx="
http://www.adobe.com/2006/mxml">
    <mx:Panel title="Module A" width="100%" height="100%">
        <mx:Button label="I am a button"  />
    </mx:Panel>
</commandmodulefr:CommandModule>

The result is a simple application that lets you load and unload modules using buttons from the main application.

image

In Practice

How you would go about using this library really depends on what you are doing, but for most implementations the Command Module Manager is probably going to be the most useful. This is because for any application of a medium to large size and for many reasons including maintainability and user experience, you are going to want to divide the application into modules. If you are using a considerable number of modules, the application is a lot easier to modify if the usage of those modules are externally defined.

For example if you have an application that has 100 modules and you wanted to use a module loader for each one, you would have to have 100 module loader declarations in your application. Every time someone added a module they would also have to add a module loader declaration, which would become very cumbersome. You could of course deal with the module loaders programmatically but you would essentially be recreating the equivalent of a module manager.

A technique which I have used on various projects that seems to be pretty straight forward is to have some external file, almost always XML, which specifies the module locations as well as other information. This file at its most basic level is just a way to declare module names and locations outside of your code, giving more flexibility at runtime.

For example if I had the following file:

<Modules>

<Module name=”ModuleA” url"=”valentino/modules/ModuleA.swf” />

<Module name=”ModuleB” url"=”valentino/modules/ModuleB.swf” />

<Module name=”ModuleC” url"=”valentino/modules/ModuleC.swf” />

</Modules>

I would then write some type of manager (referred to as a State Process Manager) class in my application to listen for particular events, and then based on those events look up a module’s URL in the external XML file and then pass them to the Command Module Loader to do the loading.

The resulting architecture looks something like the following:

image 

State Process Manager - The objective of the state process manager is to control the event flow of the application, requiring reference to the one or more command module managers, the external module definitions, and the modules.

Command Module Manager - The command module manager is just an easy way to load an unload modules in and out of a view stack using URL’s.

Module Definitions – A list of the URL’s that contain the modules to load, which can also include any other information regarding module runtime configuration.

Modules – Portions of the UI to be loaded and unloaded.

Link to the Open Source Project

https://sourceforge.net/projects/commandmodulefr/

Contributors