Saturday, July 18, 2009

Flex: Building Modular Rich Internet Applications

Why? Because you want to incrementally deliver content

A typical model for building a Flex application is to just use one SWF file. That is because by default when you create a Flex project in Flex Builder your main application MXML and all of the classes that it references are compiled into a single SWF file.

image

Flex Builder then embeds that SWF file in an HTML page where you can then upload it and the Flex content somewhere, and when people visit that page it and the SWF file are downloaded by their browser and Flex application is executed.

image

It helps to conceptualize as an application in terms of its views or screens. For example an application may consist of a screen to login, a screen to create an account, and so on. In the single SWF model that single file contains all of these different views. You begin to get into trouble when you have a lot of different views, which causes the single SWF file to become large.

For example you could have an application that has 10 different views where each view adds about 200 KB to the application size, the result is that you end up with a 1.95 MB file that the user has to download at one time to run it. This of course would be come a problem when you have a lot more views, views that are larger, or a combination of both.

image

Flex has the ability to use Modules, which allows you to break an application up into parts. Typically one would break an application up into its views (or screens). The result is an application that the end user downloads piece by piece and as needed. For large applications this is a requirement, since users don’t want to have to wait for several minutes of downloading every time they need to use your application.image

How?

I really haven’t been ever able to find a definitive source that explains all of the different ways to use modules, which is why I am writing this. When it comes to modules there are two general approaches:

  1. The text-book approach – This is the way modules are described in documentation and other Adobe writings, which does not take into account real world functional uses problems.
  2. The pragmatic approach – This is the way they are actually used in functioning applications, taking into account the plethora of bugs.

I will attempt to explain both approaches, with more emphasis on the pragmatic since a working application accompanies this writing.

Modules and Application Domains

Application Domains in the case of modules are used to determine what parts of a module are actually unloaded when they are unloaded. The following are the two methods in which this functionality is controlled:

Current Domain Method – This makes it do modules never really unload, and that their definitions are kept around for the lifetime of the application. The result is modules load faster the second time they are loaded because they never really unloaded in the first place. [image9.png]

Copied Domain Method – This is the default behavior and is supposed to allow modules to truly unload. The result is that modules always take the same amount of time to after unload since they have to be completely reloaded.

[image17.png]

For more information see the following: http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html

The Realities of Modules

Basically looking at a module wrong will cause it not to unload when using the Copied Domain (Default) Method. The following are culprits for the modules persisting, each of which I have implemented resolutions:

Even with these resolutions there is ultimately a problem that is an article unto itself regarding how the memory required to render components becomes fragmented over time, eventually preventing objects that should be eligible for collection from by collected. I will get around writing about it and the proof of its existence later, but for right now just be aware of its effects. Its effects are most noticeable in Flex applications that run at high resolutions, because the larger in size the component the more memory that is required for rendering it.

This basically means that in larger and/or graphically rich applications if you have to render a lot of content over and over you will run out of memory and there is nothing you can do about it. Using the current domain method will mitigate this problem, but then you have to be sure that your application’s definitions can fit within whatever the requirement is for client memory. Even then you will still encounter the problem within rendering memory fragmentation.

What can be done?

Pool your modules.

Once a module has been created store its instance and then retrieve it the next time it is needed. This however requires enough memory available to be able to go to every module in the application, or however modules it is possible to go to.

The result is a memory profile that looks like the following with modules in which the instance never go away:

image

Using this method you can load modules over and over again without having to worry about the issue with rendering memory fragmentation (unless there is a substantial amount of dynamic manually drawn content).

The resulting secondary load times are also much faster than when using the Current Domain Method:

image 

What are my options?

  • Pool your modules or don’t – If you pool your modules then you need to have enough memory available for the possibility that the user loads a lot of modules. Otherwise you are going to hit the problem with rendering memory fragmentation and run out of memory.
  • Use the Current Application Domain or the Copied Application Domain Method – If you use the copied domain method it will be extremely difficult to get modules to actually unload, and you will eventually run out of memory in most applications due to the problem with rendering memory fragmentation. If you use the current domain method you will mitigate the the rendering memory fragmentation problem, but you will need to be able to have enough space in memory to deal with the possibility of having to store the definitions for a large number of modules.
  • Force Garbage Collection or don’t – If you don’t force garbage collection and you are not pooling modules, then modules sometimes won’t unload. When pooling it will help memory along, but in both cases be aware then forcing garbage collection can cause problems with remoting.
  • Cleanup on module unload or don’t – If you don’t “cleanup” when not using pooling then various instances within modules are likely to leak.

How are all these options implemented?

The following is a test application featuring a ModuleManagerUtil class and a MemoryManager class.

Application: http://modular.theflexsite.net/

Please be aware that the debug version of the Flash Player always leaks modules, so if you are using the debug player just about everything is going to leak. See the following for more information: http://jvalentino.blogspot.com/2009/05/flex-memory-tip-1-debug-player-always.html

image

About the Sample Application

The ModuleManagerUtil class is used to handle loading and pooling modules.

The MemoryManager class is used to get the current amount of memory in use by the Flash Player and force garbage collection.

The buttons on the left are used to load different modules. The simple modules just contain panels, the complex modules contain DataGrids, and the popup module will load a module as a popup.

The bottom of the page is a JavaScript plotting application done using Flot, so display memory without interfering with what is going on in the Flex application.

Monday, June 22, 2009

Flex + BlazeDS + Google App Engine + Java + Eclipse

Why?

Because you want to write a Flex application that requires that the server be able to push data to the client, you want a highly scalable server so you decided on the Google App Engine, when provided with the option of Python versus Java you found Java more accessible, and Eclipse is an easy way to link it all together.

  • Flex – used for the graphical user interface
  • BlazeDS – used for Flex to Server remote objects and provides the ability for the server to push data to the Flex client
  • Google App Engine – used for hosting the server portion of the application
  • Java – the language used for constructing the server potion of the application
  • Eclipse – an easy way to build, manage, write code, and deploy

There are lots of other options though, in general with Flex you are aiming for a way to deal with remote objects and/or server data push + some way to persist data on a server that ties to some language + some IDE. This is just one of many possible configurations with an emphasis on relatively free parts.

It is also apparently difficult to get all of things working together, so I thought it would help for others if I shared the steps.

In this example I basically combined the two following projects into one to use the Google App Engine to show basic remote objects and messaging:

If you want more details into the how remote objects and messaging works see those examples.

Requirements

1. Creating the Server

1.1 Press the “New Web Application” button in the Eclipse toolbar

image

1.2 In the “New Web Application Project” window specify a project name, the package, and for the rest use the default settings then press the “Finish” button.

image

1.3 If you are like me and already run another server on port 8080, then you need to change the project settings to use a different port. You can do this by opening the debug menu and selecting “Open Debug Dialog…”

image

1.4 Specify a new port to be used and save these settings.

image

2. Adding BlazeDS to the Server

2.1 Assuming you have obtained the BlazeDS WAR file, unzip it using some ZIP program

image

2.2 Open the BlazeDS web.xml file and copy the mappings into the web.xml in your Google test project.

The web.xml file is located in MyGoogleServer/war/WEB-INF

image

The resulting web.xml file should look like the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

  <!-- Default page to serve -->
  <welcome-file-list>
    <welcome-file>MyGoogleServer.html</welcome-file>
  </welcome-file-list>
  <!-- Servlets -->
  <servlet>
    <servlet-name>greetServlet</servlet-name>
    <servlet-class>com.example.myproject.server.GreetingServiceImpl</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>greetServlet</servlet-name>
    <url-pattern>/mygoogleserver/greet</url-pattern>
  </servlet-mapping>
  <!-- Begin BlazeDS Stuff -->
  <!-- Http Flex Session attribute and binding listener support -->
    <listener>
        <listener-class>flex.messaging.HttpFlexSession</listener-class>
    </listener>

    <!-- MessageBroker Servlet -->
    <servlet>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <display-name>MessageBrokerServlet</display-name>
        <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
        <init-param>
            <param-name>services.configuration.file</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>

</web-app>

2.3 Copy the BlazeDS flex directory into MyGoogleServer/war/WEB-INF

image

2.4 Open the services-config.xml file and change the three instances of {server.name}:{server.port}/{context.root} to your server name, which in the case of this example is localhost:9000. When you deploy this thing to Google you will of course need to change it.

image 

2.5 Open the appengine-web.xml file and add the node <sessions-enabled>true</sessions-enabled>

image

2.6 Copy all of the JAR file in the BlaseDS lib directory to your lib directory, which in this example is MyGoogleServer/war/WEB-INF/lib

Before copy:

image

After copy:

image

2.7 If your server will be at a different location than your client, then you need to create a crossdomain.xml file to grant the client access.

image

In this case I like to share, so I am granting the entire internet access to the web services here. Normally you wouldn’t want to do this for reasons that should be obvious:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "
http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <allow-access-from domain="*" />
</cross-domain-policy>

3. Creating server-side logic

3.1 Create a class that will be used as a remote object that will just return “Hello”

package com.example.myproject.hello;

public class Hello {
    public String sayHello() {
        return "Hello World";
    }
}

3.2 Open the remoting-config.xml file and add the following node to map the Hello remote object:

<destination id="Hello">
        <properties>
            <source>com.example.myproject.hello.Hello</source>
        </properties>
</destination>

3.3 Open the messaging-config.xml file and add the following node to be able to use the chat variable for messaging:

<destination id="chat"/>

4. Creating the Flex client

4.1 Run the Google Server project

image

4.2 From the File menu create a new Flex Project

image

4.3 Specify the project name and set it to be a J2EE application server and don’t use WTP.

image

4.4 Uncheck the box to use the default LiceCycle Data services server and specify the location of the war directory of the Google Server project, and change the URL to reflect the the location of the server. Since I am planning on running the client on a different machine than the server, specify the Output folder to be bin-debug.

image

4.5 Specify the output folder URL to match the location on your local test server.

image

4.6 Run two instance of the Flex application, and notice how the sayHello button tests the Hello.java class, and you can use the Send B button to send message back and forth the the “chat” variable.

image

4.7 The Flex Code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="
http://www.adobe.com/2006/mxml" creationComplete="consumer.subscribe()">
    <mx:RemoteObject id="blazeService" fault="faultHandler(event)" source="hello.Hello" destination="Hello">
        <mx:method name="sayHello" result="resultHandler(event)" />
    </mx:RemoteObject>
     <mx:Consumer id="consumer" destination="chat" message="messageHandler(event.message)"/>
    <mx:Producer id="producer" destination="chat"/>

    <mx:Script>
        <![CDATA[
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            import mx.messaging.messages.AsyncMessage;
            import mx.messaging.messages.IMessage;
            private function send():void{
                var message:IMessage = new AsyncMessage();
                message.body.chatMessage = msg.text;
                producer.send(message);
                msg.text = "";
            }
            private function messageHandler(message:IMessage):void{
                log.text += message.body.chatMessage + "\n";
            }

            private function faultHandler(fault:FaultEvent):void {
                result_text.text = "code:\n" + fault.fault.faultCode + "\n\nMessage:\n" + fault.fault.faultString + "\n\nDetail:\n" + fault.fault.faultDetail;
            }
            private function resultHandler(evt:ResultEvent):void {
                result_text.text = evt.message.body.toString();
            }
        ]]>
    </mx:Script>
    <mx:Button x="10" y="132" label="sayHello" width="79" click="blazeService.getOperation('sayHello').send();"/>
    <mx:TextArea x="10" y="27" width="319" height="100" id="result_text"/>
    <mx:Panel title="Chat" width="100%" height="100%">
        <mx:TextArea id="log" width="100%" height="100%"/>
        <mx:ControlBar>
            <mx:TextInput id="msg" width="100%" enter="send()"/>
            <mx:Button label="Send B" click="send()"/>
        </mx:ControlBar>
    </mx:Panel>

</mx:Application>

5. Last Thoughts

I haven’t tried it, but apparently if you want to get remoting-only BlazeDS to work you have to do the following hack: http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html

Friday, June 12, 2009

Flex Memory Issue #4: Modules and Application Domains

“ApplicationDomains are pretty much a neverending source of confusion and suffering…”

- Roger Gonzales, helped in the design of Application Domains in Flex

If you are using modules in Flex whether you are aware of it or not, you are using Application Domains. In particular I have had several issues with them and their effects on memory. An Application Domain is a container for discrete groups of classes, which are used to partition classes that are in the same security domain.

What? Yes, I know. That definition is from Adobe’s asdoc for the ApplicationDomain class, and it really doesn't tell you what it has to do with modules. For a start Roger Gonzales did a great job of explaining the history and purpose of the Application Domain on his blog, located at http://blogs.adobe.com/rgonzalez/2006/06/applicationdomain.html.

To attempt to summarize the Application Domain it is essentially a way to contain AS3 definitions, which effects how modules load and unload. With modules Application Domains let you do one of two things, which I refer to as the “Current Domain Method” and the “Copied Domain Method”

Current Domain Method

Example Usages:

var info:IModuleInfo = ModuleManager.getModule("com/foo/FooModule.swf");
info.load(ApplicationDomain.currentDomain);

This loads a module into the current Application Domain, so that when it unloads the class definition stays in memory but the rest of the module related instances are supposed to go. The next time the module is loaded the class definitions are already there so it loads faster.

For example if you have an Application that has 3 modules and you load one module at a time using the Current Domain Method, unload them, and load the next module in the sequence you get the following memory profile assuming you force garbage collection (http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html) after each unload:

 image

* Assumes modules are all the same size, garbage collection is forced after unload, memory snapshot is taken using System.totalMemory, and memory snapshot is taken between unload of previous and load of new

Notice that the memory peaks after all of the modules are loaded, levels off when those three modules are again loaded, and then only drops down slightly after all the modules are unloaded. The remaining memory isn’t just Flash Player stuff, it is also the definitions for the modules classes. This means that when using the Current Domain Method, modules will never truly unload.

For another example if you look at the time it takes those module to load for the 3 module scenario using the Current Domain Method, you get the following:

image

The initial load times for each module are much greater than the amount of time for next time the same module is loaded. This is because the definitions for those modules are stored in the current Application Domain for the application when using the Current Domain Method.

Theoretically, when would one use the Current Domain Method?

You would want to use the current domain method if you were not worried about the user loading enough modules to cause the application to go out of memory. When you are using this method you are essentially caching the module definitions when you load them, allowing for the module to be loaded much faster the next time it is needed. To summarize it requires more memory in order to achieve faster load times.

Copied Domain Method

This is what happens when you use the load function of the ModuleManager and specify the parameter as a new Application Domain using the current Application Domain. This is also the default behavior when not using a parameter at all.

Example Usage:

var info:IModuleInfo = ModuleManager.getModule("com/foo/FooModule.swf");
info.load();

or…

var info:IModuleInfo = ModuleManager.getModule("com/foo/FooModule.swf");
info.load(new ApplicationDomain(ApplicationDomain.currentDomain));

This loads the module into a new Application Domain so that they are no references to keep module definitions from unloading. The result is that when you unload a module all of the related classes are supposed to entirely unload. The amount of time required to load a module never changes, because it has to be completely loaded each time.

For example if you have an Application that has 3 modules and you load one module at a time using the Copied Domain Method, unload them, and load the next module in the sequence you get the following memory profile assuming you force garbage collection (http://jvalentino.blogspot.com/2009/05/flex-memory-issue-3-garbage-collection.html) after each unload:

image 

* Assumes modules are all the same size, garbage collection is forced after unload, memory snapshot is taken using System.totalMemory, and memory snapshot is taken between unload of previous and load of new

Notice that when the all modules are unloaded the memory is supposed to go back down to where it was before the first module was loaded.

For another example if you look at the time it takes those module to load for the 3 module scenario using the Copied Domain Method, you get the following:

 image

The amount of time that it takes to load each module never changes, because each time the module has to be completely loaded. It is my understanding that the reason for this is because when using the Copied Domain Method you are not adding AS3 definitions to the current domain, so those definitions can fully unload when the module is unloaded.

Theoretically, when would one use the Copied Domain Method?

You want want to use this method if your application was under some kind of memory constraint, or if there were so many modules that it could cause the Flash VM to run out of memory. The down side to this is that you have to fully load each module every time you need it, whether it has already been loaded or not.

Current Domain Method versus Copied Domain Method in the real world

In large and stylistically complex applications in the real world, the copied domain method has provided me with a world of trouble when it comes to memory. The memory behavior is erratic to say the least in the following ways:

  • Even when forcing garbage collection the memory jumps around erratically like nothing is being done at all.
  • If you run the same exact scenario over and over again you get different results. One time memory averages 30 MB, another 50 MB, and another time it just runs out of memory

I know what you are thinking, “there are other memory leaks in the application!” That would be incorrect, as the profiler shows no leaking and if you change to the Current Domain Method the problem is gone in the particular scenario in which this happens. It is that point which I became completely confused and I was even able to talk to Adobe about it through a third party, but I was never able to get an answer.

The scenario in particular was the loading and unloading of two different modules over and over again about 100 times. Load Module 1, unload Module 1 and load Module 2, unload Module 2 and load Module 1, etc.

When using the Copied Domain Method each time I ran this scenario I got different results:

image

For example the first attempt at this scenario was fine, the second attempt ran out of memory, and the third attempt went up in memory and never came back down.

If you take that same exact scenario and make it use the Current Domain Method you get the following:

image

Using the Current Domain Method seemed to have fixed the memory issue in this scenario, but by using this method I was stuck with modules with definitions that never get unloaded.

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