Tuesday, February 9, 2010

Dear John, How do I unload Flex modules?

Question asked by Joshua.
Unloading modules is a difficult thing to do, and is near to impossible in Flash Player 9. Originally this article clued my into what was going on: http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html. Essentially to get modules to truly unload you have to get rid of all the references to them, and be using the "Copied Domain Method." The copied domain method is described here in detail, along with its effects on memory: http://jvalentino.blogspot.com/2009/06/flex-memory-issue-4-modules-and.html.
Assuming you are using the Copied Domain Method, you then have to deal with the following areas of leakage as mentioned in the originating article:
I essentially handled these area of leakages by iterating recursively through every component within a module class after unloading, removing state, removing bindings, removing common listeners, reseting the EffectManager, and then forcing garbage collection using what is called the local connection hack.
The problem with this though is that there will always be memory accumulation even if references are removed. This is due to a largely unknown and undocumented issue known as "Rendering memory fragmentation." I have discussed this issue with several engineers at Adobe through a client which I cannot name, and they are at least passively aware of it but it is an issue with the Flash Player itself. The article at http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/ hinted at what was going on, which lead me into a full investigation to verify the problem.
Basically the Flash Player operates on what is called an Elastic Racetrack (http://www.onflex.org/ted/2005/07/flash-player-mental-model-elastic.php), which ends up with the memory used of AS3 object allocation and the memory used for rendering getting on the same page in memory. When the garbage collection runs the allocation space is not cleaned because the blocks contain active rendering memory and vice versa. This makes it to where the garbage collector fails to clean things, which causes leaks. Since the issue is rendering related it is more prevalent in application that are graphically intense and run at large resolutions, like kiosks. It is for these reasons that I recommend that most applications pool modules, so that the rendering and object instantiations through allocations are minimal.
In the end it will depend on how many "modules" are in your application, how big they are, and if they are really modules. It is quite common for application to incorrectly use modules because they followed the examples released by Adobe, which cause the module definitions themselves to be compiled into both the module SWF and the main application SWF. Flex operates on a compile by reference basis, so if your application has direct reference to a module class that module class gets compiled into both the module SWF and the main application SWF.

No comments: