Friday, March 26, 2010

ComboBox memory leak

A ComboBox is a very commonly used control. It looks very harmless but can be very dangerous as it leaks memory.

A Flex bug has been filed and here is the link. But Adobe is lazy and they will do nothing other than sit over the bug.

You can download the source code from here for the below example if you would like to profile and see the memory leak in the profiler.

The demo contains 2 custom components.
CustomComponent1: is a very simple component which contains a TextInput and CustomComponent2.
CustomComponent2: is also a very simple component. It contains a dropdown.
A button in the application removes the CustomComponent1. CustomComponent1 being a hello world type component, it should be garbage collected once it is removed from the displayList. But it does not. Check the image below.


The above screenshot is taken from the profiler. CustomComponent2 leaks and the references have been expanded. One of object referencing it is mx.controls.List. But List is really not the child of CustomComponent2 than why would it reference it? The document is CustomComponent2 hence all children and grand children of CustomComponent2 have the document property set to CustomComponent2 unless there is another document that contains the grand children. The List's document property is CustomComponent2. Finally, the List is being referenced by SystemManager as highlighted in red.

But why is the List referenced by the SystemManager? A ComboBox contains a dropdown which is really a List. The dropdown though referenced by the ComboBox is really not the child of the ComboBox. It is a Popup. Check ComboBox.as and you will see a lot of PopupManager.addPopup(_dropdown) lines. It is made to look as if it is dropping out of the ComboBox. A popup's parent is always a systemManager. That explains the relation between ComboBox -> dropdown (List) -> SystemManager.

Check this comment in the ComboBox.as ...

private function removedFromStageHandler(event:Event):void
{
// Ensure we've unregistered ourselves from PopupManager, else
// we'll be leaked.
destroyDropdown();
}

... despite knowing about the potential leak, the leak still exists.

Solution:
Extend ComboBox and add this method ...


//add event listender in the constructor
addEventListener(Event.REMOVED_FROM_STAGE, this_onRemovedFromStage);

...
...

protected function this_onRemovedFromStage(evt:Event):void {
if (mx_internal::hasDropdown()) {
var dd:ListBase = dropdown;
if (dd && dd.parent) {
dd.parent.removeChild(dd);
}
}
}


Now imagine an application which contains ...
CustomComponent1 which contains
    |____CustomComponent2 which contains
        |____CustomComponent3 which contains
            |____ComboBox which references
                |____dropdown whose parent is
                    |____SystemManager

The dropdown leaks hence the entire chain of components will leak. This bug has been reported to Adobe but I am not sure why they haven't fixed it.

Labels: , ,

4 Comments:

At March 31, 2010 at 9:23 AM , Blogger Nate Beck said...

Flex is open source... you have the fix... why don't you commit it back?

 
At April 7, 2010 at 9:46 PM , OpenID richardchaven said...

Wow. I don't know how much you paid for the Flex SDK, but it isn't enough to cop an attitude like that. They do not exist to solve your problems.

If the new Spark controls have leaks, Adobe will fix them. They have no incentive to fix a deprecated set of components.

 
At April 11, 2010 at 9:31 AM , Blogger Prashant Jain said...

richardchaven,
Well they are really not solving my problem only. It is a Flex community problem. It's not about Spark or Halo. A lot of bugs were reported when Spark didn't exist. These bugs are very obvious and easy to fix but they have not been fixed even after 6-12 months. I recently spent 18 hours on a bug that was reported 6 months before. I wonder how much money is lost because of known bugs not getting fixed.

ADOBE IS LAZY is a quote from Steve Jobs which has become quiet famous. I was quoting Steve Jobs.

 
At June 2, 2010 at 12:13 PM , Blogger Matt Bastress said...

Thanks for posting this fix. I will pay more attention to the known memory leaks in the Adobe bug database.

It is taking quite a while for us to root out leaks in our apps, no thanks to Flex Profiler and Flash Profiler, both of which are buggy or crash often.

richardchaven, I don't know why someone would use the Flex SDK, except to solve a problem. We are considering abandoning Flex (and the licensed software we pay Adobe for) simply because it isn't worth the trouble. I suspect Adobe would care about that.

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home