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.

1 comment:

quatrol said...

Interestingly enough, there is a similar issue with the 'Focus' logic which is also reported on the Adobe bug base (https://bugs.adobe.com/jira/browse/SDK-14781).