What We Know About Unloading Modules

As of this writing, the Flex team does not know of any scenario that pins a module in memory forever assuming the developer has cleaned up all references.
If you have a module that does not unload, the steps to diagnose the problem are:
1) Make sure the module is being loaded into a child applicationDomain (use default parameters for the load() method in most cases)
2) Use the profiler to make sure there are no references to objects in the module. The most common causes of leaks are:

a. Styles. Even without any mx:Styles tag in your MXML, if a module uses a component that is not used by the main application, the module will register the default styles for that component with the StyleManager and pin the first instance of the module. You can use the -compiler.keep-generated-actionscript compiler option to see which default styles the module and main application are using. You can use the -compiler.keep-all-type-selectors compiler option on the main application to force the main application to register the default styles for every component in the defaults.css file. Prior recommendations to load style declarations via runtime CSS (StyleManager.loadStyleDeclarations) are withdrawn. Runtime CSS modules register styles in a different way so they can be unloaded and will not prevent this problem.
b. Resources. If a module uses components that use ResourceBundles that are not used by the main application, those resource bundles will get registered with the ResourceManager and pin the first instance of the module. You can use the -compiler.keep-generated-actionscript compiler option to see which resource bundles the module and main application are using. You can force the main application to have those additional resource bundles by adding the resource bundle metadata to the main application. For example, to add the “controls” resource bundle, you would add to the main application MXML file: [ResourceBundle(“controls”)] If you are loading your resource bundles as modules, make sure the resource modules have completed loading before loading the module that is being pinned.
c. ExternalInterface.addCallback. Modules should not use ExternalInterface.addCallback. That registers the method with the browser and there is no way to unregister it at this time. The recommended practice is to have the main application register a method that will call a function reference and put the module’s method in that function reference, then set the function reference to null when the module unloads.
d. Timers and other timer mechanisms. The use of Timer, setTimeout(), and setInterval() can cause leaks. Timer’s must be stopped and have their listeners removed, setTimeout and setInterval must be paired with calls to clearTimeout() and clearInterval().
e. Listeners to events from objects outside of the module. Use weak references or make sure to remove the event listeners. Remember, when you call a.addEventListener(“foo”, b.someMethod), it is ‘a’ that has a reference to ‘b’, not the other way. If you are listening to a parent or stage or singleton, those objects now have a reference to the object that whose method is going to get called and can cause leaks.
f. Focus. If an object in the module has focus, the FocusManager will still have a reference to the module. A good UI will move focus to some other object outside the module before removing the module.
g. RemoteObject. If a module brings in a data class that is going to be part of a server query, that class can get registered with the Player and result in a reference to the module. Link data classes into the main application when possible.
h. Loaded Images. If a module loads an image, that image must be unloaded otherwise the player will still keep some data buffers around.

3) Once there are no references to objects in the module, the Flash Player can still keep a module in memory for a while if objects in the module ever had focus. Other activity in the application, such as typing and clicking will eventually release references to the module and the module will be freed from memory. Try typing and clicking in the main application or another module and see if the pinned module gets garbage-collected.
4) Debug-versions of a module on the Debugger Player can also lead to a module being stuck in memory. Debug-versions contain debug information that can get registered with the debugger and not released. The final test is always to use release versions of the modules and application on a release version of the player.
A word (or 50) about unloadAndStop(): UnloadAndStop is a new API in player 10. It is intended to stop audio and video playback and the timeline, but does not claim to deference all references to classes in a loaded SWF and has not been proven to help modules free themselves from memory. While it may help child applications loaded via SWFLoader, it is not used by modules. Modules actually call Loader.unload() on themselves immediately upon completion of loading so that they will be available for garbage collection once all references to objects in the module have been removed. This is because a module can be used to make multiple instances of the various classes in the module and we don’t want to add the overhead of tracking all of those instances or require that a developer have some other way of tracking when all references to a module have been removed so they could know when to call unload().

51 Responses to What We Know About Unloading Modules

  1. Jinni says:

    Great information for develops who suffered memory leaking issues a lot. ~ Another reference trap could be with EffectManager, which holds static references of the last effect played/created, etc. And typically the effect instance has a reference to its target (could be components in a module).

  2. thanks lot for the detailed list. i hope that these problems will be fixed soon by adobe. silverlight is already on the horizon as a serious competitor (see also what joa ebert wrote: http://blog.joa-ebert.com/2009/08/10/flirting-with-silverlight/) and i think with such weak points adobe will fall behind when it comes to build large scale robust applications, espacially when you consider C# as a much more powerful language then AS3.

  3. okgautam says:

    Please help me with Flex technical queries.
    I am using Flex Open SDK 3.3 in my project.
    In Flex Runtime localization and running issue with the Flex repeater components, when ever I change my application locale
    1. How to Handle of Flex repeater during localization?
    2. Once I update the application locale how to update the repeater comp.
    3 .what should be the best practice to update a MXML component or Action Script comp ?
    2. How could I get the browser locale information and pass it to flex application.
    In fire-fox the java-script works fine to find the locale before application starts, but in Internet Explorer the application gets already loaded before the script returns the value for locale.
    I am using a jsp code to get the locale of the client browser.
    Please provide us some best practice on passing browser information to flex application.
    Nice to have: A single API which would return the browser locale
    Browsed some examples in adobe site; but a small template would help us a lot.

  4. Thanks for a very informative read Alex. A week or so back I was really struggling to get modules garbage collected and just couldn’t get some to be GCd at all. This was due to the typing problem and despite typing in the main app they still didn’t seem to get GCd but perhaps I didn’t wait long enough.
    We use remote objects in our modules. Will this stop the modules being GCd as well? Do we have to have all Remote Objects in the main application?
    What is the recommended way of implementing styles now? Compiling them into the module and main app?

  5. William Draï says:

    Thanks for these highly valuable information.
    Concerning the poing g, I guess this has something to do with flash.net.registerClassAlias. Is there any way to manually unregister a class alias when a module is unloaded.

  6. TK says:

    What about loading Modules? When loading a Module into my application with new nightly builds of the Flex 4 SDK, my Flex app framerate will drop to 0 and the whole application will get bogged down. In the first public beta of the Flex 4 SDK, this problem wasn’t present.

  7. Great article. I still have some problem with modules unloading. I’m going to implement all recommendation you give. Will see how it goes.
    Thank you Alex.

  8. Sean says:

    Great article, it helped me alot.
    I noticed though that if I have a datagrid with drag enabled and the user drags an item, then the module will not unload. Do you know why this would happen?

  9. Russ Watson says:

    Thanks for the info Alex, the “ExternalInterface.addCallback” tip was the biggest eye opener.
    I’ve also added one of our techniques on my blog: http://wp.me/pCFcS-r

  10. Alex Harui says:

    Please ask your question on an Adobe forum. That is not related to the post’s topic.

  11. Alex Harui says:

    RemoteObject objects and SOAP objects also go into a type registry and should not be in modules. Link them into the main app or a separate “data-only” shared code module that is small and doesn’t matter if it unloads

  12. Alex Harui says:

    I tried passing in null for the class alias and was not successful. You can pass some other class from the main app, but that seems like a hack. Better to partition the data classes into the main app or their own module especially if the module may be reloaded later.or other modules share the same definitions.

  13. Alex Harui says:

    If you have a simple reproducible test case, please file a bug.

  14. Alex Harui says:

    We just found a bug where the interval doesn’t get cleared during drag scrolling. Should be fixed in Flex 4 beta2.

  15. Arnoud Bos says:

    Hi Alex,
    Nice but somewhat worrying list…
    we are building a huge app wich loads subapps (not modules but real separate applications build in flex). These subapps can be from third app developers etc… We use swfloader with the load for compatibility option set to true. This would mean that the sub app is loaded in a sibling application domain of the host app and that the subapp has it’s own versions of all classes right?
    Even if this architecture is more separated and less integrated than modules we still have a problem unloading the subapplication if we use styles in the subapp.
    so if i call setStyle(“color”,”red”); in the subapp, the subapp doesn’t unload, removing the setStyle lets us remove the subapp.
    The restriction “just not to use styles in subapps” is too big. Is there any option for flex 3.4 to fix this? I’d even go for monkeypatching the stylemanager if it’s possible. Any help would be highly appreciated as i’m the one promoting flex/air and well, these kind of bugs can eventually lead to a technology switch as users of the system would run out of memory soon. I by no means want that!
    thanx,
    Arnoud

  16. great and useful information for developers. the one great problem will be with the effectmanager since it show the last played effect.

  17. Hi Alex, you can solve a lot of problems about modules patching some managers. For instance you talk about the focus, so if you take the implemetation of FocusManager you will find a variable called _lastFocus which stores a IFocusManagerComponent. Clearly this is a bad thing because if you try to removre a component it couldn’t be disposed because there is someone who reference to it. So you can try to patch it using private accessor based on a weak dictionary with the component as key.
    i hope it can be useful
    thanks for your articles
    Matteo

  18. Joe says:

    Thanks for this great info! You are definitely one of the smartest people I have found on this subject. Do you know of where I can go or could you post some examples of how to do points 2a, 2b and 2f. Also is there any material (books, tutorials, etc) on memory management practices. Any suggestions you might have would be greatly appreciated. Thanks again!

  19. Miha says:

    Hey Alex, great post about unloading modules, unfortunately this doesnt solve my problem of unloading a sub-application. Here’s the code (it’s really small):
    (Replace ! with tags)
    Main app:
    !?xml version=”1.0″ encoding=”utf-8″?!
    !s:WindowedApplication xmlns:fx=”http://ns.adobe.com/mxml/2009″ xmlns:s=”library://ns.adobe.com/flex/spark” xmlns:mx=”library://ns.adobe.com/flex/halo”!
    !s:layout!!s:VerticalLayout/!!/s:layout!
    !s:Button label=”Load” click=”swfloader.source=’TestAirSubApp.swf'”/!
    !s:Button label=”Unload” click=”swfloader.source=null;System.gc();”/!
    !mx:SWFLoader id=”swfloader”/!
    !/s:WindowedApplication!
    Loads subapp:
    !?xml version=”1.0″ encoding=”utf-8″?!
    !s:WindowedApplication xmlns:fx=”http://ns.adobe.com/mxml/2009″ xmlns:s=”library://ns.adobe.com/flex/spark” xmlns:mx=”library://ns.adobe.com/flex/halo”!
    !/s:WindowedApplication!
    As you can see my sub-app is nothing but an empty swf-the skeleton generated by new application. It doesnt have styles, timers or anything at all. Compiled with same version of Flex SDK, even putting it in a different appDomain or trying the release version, results are always the same. Every load increases memory per 1 instance and unload doesnt remove anything from memory. A memory leak. The only thing the subapp has are the classes from the Flex framework and even this dont get garbage collected, so how can I possibly solve this memory leak ?

  20. Alex Harui says:

    I don’t think we support WindowedApplications loading other WindowedApplications. The child WindowedApplications gets hooked in ways that don’t work very well. The sub-application should be based on mx:Application

  21. Alex Harui says:

    The expectation is that your code will set focus to something else (a good practice for accessibility) and that will free the reference from _lastFocus

  22. Alex Harui says:

    If you own all the code you can put all of your styles in a css file referenced from the main app’s mx:Style block, then use -keep-all-type-selectors
    If you know all the resource bundle names, list them all in the main app
    Choose an appropriate control that should receive focus and call setFocus() on it.
    You’ll get more timely responses if you ask on one of the forums.

  23. Hey,
    awesome article, really instructive. I translated it in french on my blog:
    http://www.flex-tutorial.fr/2009/10/29/flex-modules-decharger-unload-correctement-ses-modules/
    Thanks for the infos,
    Fabien
    http://www.flex-tutorial.fr

  24. Simon says:

    Am I write to assume from your list that if I have an application with one module required to perform some sort of remote request and then unload I must either (a) have the main application handle all the remoting logic (b) build a further second module to handle the remoting logic?
    I guess that removes the notion of Modules who’s sole role is to instantiate a Remote Object, handle the data and then unload?
    What if the main app instantiated the Remote Object and various other classes referenced instances of this, would they be GC’d if they removed their instance on disposal?
    Cheers,
    Simon

  25. Jude says:

    Hi All,
    I am struck up mid of something could you please help. I am using Flex builder 3 and Weborb PHP application. In which i am communicating via remote objects using web services.
    Now my problem is i am trying to execute html file or swf but its giving error that its not connecting with weborb.php file. Whats the cause for this? where should i configure and execute.
    Please help.
    Thanks in advance
    Jude

  26. Alex Harui says:

    Yes, the main app can have the RemoteObject instance and related classes that will be serialized. You don’t want anything that gets serialized or does the serialization in a module.

  27. Alex Harui says:

    Unfortunately, that’s out of my jurisdiction. I’d ask on the forums.

  28. Darrell says:

    Another type of module leak is caused by modules registering singletons via Singleton.registerClass(). The class reference from the Singleton in the main application to the module pins the module in memory. The safest thing to do is always define PopUpManager and DragManager in the main application (see below).
    import mx.managers.PopUpManager; PopUpManager;
    import mx.managers.DragManager; DragManager;

  29. Ben says:

    I’m trying to figure out why my sub-applications won’t unload. Can you explain this Object References table (I’m using the profiler in Flash Builder 4)?
    _SeminarPlugin_mx_managers_SystemManager (2 Paths)
        Path 1
            _SeminarPlugin_mx_managers_SystemManager
            mx.core:FlexLoader – [child0]
            mx.controls:SWFLoader – contentHolder
            Function – [savedThis]
            flash.display:LoaderInfo – [listener0]
        Path 2
            _SeminarPlugin_mx_managers_SystemManager
            flash.utils:Dictionary – [key6]
            Class – allSystemManagers
            Object – SystemManager

  30. Hi Alex,
    When building our website – http://www.flexdownloads.com, we hit a number of issues using modules. Technical and architectural. We found them to be a bit buggy…contentions around which module loaded which Flex class first and also challenges around histoty mgmt, back button and bookmarking.
    Finally, we had to give up and go without modules. Not sure if flex 4 changes things, but a small initial load is what most want for sure.
    When you have some spare time, appreciate your visiting our website…its made in flex and for flex and intended to grow the flex community. Free is best but a bit of profit can be a strong motivator for the numerous developers out there so most of the components sell for under $10

  31. Alex Harui says:

    That was kind of hard to read, but Path1 looks like the SWFLoader has not unloaded the sub-application. Path 2 will go away when Path1 is finally broken.

  32. Alex Harui says:

    We’ve recently fixed a few bugs around multiple requests for the same module. If you know of other bugs, please file them.

  33. rmunix says:

    Hi Alex,
    First of all GREAT WORK! This clears a lot of questions.
    Two Quick questions:
    If Timers/Intervals must always be stop before removing them or clearing them. Why is it not built into the API to stop the timer when the remove call is made. Just wondering, if the thing is running and we know we wont be able to remove it if it is running why doesn’t the API stops it automatically.
    Second question is more of a few questions in one. Do all the things you mention above apply with relation to loading sub-applications? If not what are the differences.
    Thanks again, and in advance for your reply.

  34. Alex Harui says:

    I suppose they could have cleared the timer if nobody was listening any more.
    Everything in this post also applies to sub-applications.

  35. Jeff says:

    Alex,
    Excellent article, which I had seen it before.
    Re: loading images, would this affect image assets loaded by a style declaration? If so, how would you get those to unload?
    Also, what of these issues have been resolved for Flex 4? I need to have some confidence that the approach I am taking will work.
    Jeff

  36. If you are debugging a memory leak in a Flex 4 sub-application or module please keep this bug in mind: http://bugs.adobe.com/jira/browse/FP-3859.
    The leak seems to show itself when you allocate an instance of Vector and the base type is not in the parent ApplicationDomain. This will cause the sub-application to be leaked. The leak does not happen when Flash Player types are used or when RSLs are used because RSLs load all the classes into the main application’s ApplicationDomain.
    One example of the leak is http://bugs.adobe.com/jira/browse/SDK-25357. The sub-application would leak if it showed scrollbars. The problem came down to allocating an instance of Vector. in Path.as. If the base type, PathSegment (inner class of Path), was defined in the main-application, then the leak did not happen.

  37. Alex Harui says:

    In our tests, embedded images do not leak memory and shouldn’t prevent a module from unloading.

  38. Muhammad Zubair says:

    Does WebService object also consider to be a remote object?
    I am building my own customized components which extends from my another customized class, in which I am using WebService object. My base class is responsible for all communication of web-service.
    Now my question is
    “If I used by customized components in module, does it cause leaking? (as each component have its own web-service object.)”
    few other questions in my mind:
    1) What is the best way to use CSS in modules? (keep in mind that my CSS have some embedded assets). Right now I am using through mx : Style tags.
    2) In main app I have Only 1 button, which loads a module, and in the module I have a Tree control with some static data in it. Now if I unload the module without clicking any Item of the tree then it doesn’t leak, but when I clicked on any item it goes leak (never unload).
    Please help me… I am desperately and anxiously waiting for your reply
    Thanks
    Zubair

  39. Ged says:

    Hi Alex,
    I’m still trying to digest this – with a worried look on my face.
    a. Styles. Even without any mx:Styles tag in your MXML, if a module uses a component that is not used by the main application, the module will register the default styles for that component with the StyleManager and pin the first instance of the module.
    Is this true?
    If you have a custom component in your module that is not used in the main app, with styles that are not used in the main app then you must register the style in the main app or the module won’t unload.
    In short as soon as you refer to any style unique to a module you pin the module. So styleName=”moduleGuidanceText” is a no no unless “moduleGuidanceText” is FIRST registered in the main app ?
    ps) Great Flash player GC (that we can predict and control) has got to be a future must-have if we are going to run cool apps on devices.
    All the best
    Ged

  40. Alex Harui says:

    1) In Flex 4, mx:Style tags will no longer cause leaks.
    2) The profiler will probably tell you that FocusManager has a reference to the Tree. Set the focus somewhere else before unloading.

  41. Alex Harui says:

    Yup, your understanding is correct, but in Flex 4, styles are per-module and it should no longer be a problem

  42. Ged says:

    Reading from your previous embedded fonts post
    http://blogs.adobe.com/aharui/2010/03/flex_and_embedded_fonts.html
    :
    “And because a TextField or TextLine can have only one SWF context, it means that all fonts displayed in a TextField or TextLine must be embedded in the same SWF. If you must mix, you will have to register the font and deal with the fact that the SWFs containing the fonts may never unload.”
    Please can you confirm that when using Flex 4 modules – A module that use an embedded font that is not embedded into the Module swf, will be pinned / not unload?
    Thanks

  43. marumaro says:

    Hi Alex, thanks for this great article.
    I wanted to know if there was a workaround/fix for the problem regarding Flash player keeping modules’ references for a while ?. In my application I have 2 screens (screen A : in which the user can’t type anything, screen B : where the user can input data). When i go from screen B > screen A, the flash player keeps a reference to a screen B module even though there are no more object references and everything is removed from stage.But If I type anywhere on Screen A, the module gets garbage-collected like you said, but i can’t force the user to press a key when he doesn’t have to 🙁
    Thanks.

  44. Alex Harui says:

    If a module uses and embedded font from another module, I wouldn’t expect that to cause a leak. If you have a simple test case, file a bug.

  45. Alex Harui says:

    Maybe have a small focusable object somewhere on screen A

  46. Amanda says:

    Wow! Thanks for the info. I had been tearing my code apart (and my hair out) trying to find why I had 2 instances of each of my modules in memory regardless of how many times I loaded/unloaded them. After forcing GC I could get them down to 1 instance each but never to zero(I assume that’s the focus issue you talk about). After removing my styles I got it to 0 instances in memory.AWESOME! Now off to put my code back together again…

  47. Michael says:

    Hi Alex,
    very helpful article. I’ve got a similar problem as Miha (postet 12:54 PM on September 23, 2009) using Flex SDK 3.3. I loaded Modules in Modules using ModuleManager, but they do not unload even if the loaded modules consist of empty VBoxes (without any additional Styles etc.). Do you know any alternative how to load Modules in Modules and unload them.
    Best regards

    • Alex Harui says:

      Make sure you aren’t getting some other leak like a resource leak. Also make sure you are loading the sub-module as a child of the module. Other than that, you may have to debug and profile to see what is going on.

  48. Ben Humphrey says:

    Alex, you are the Flex Grand Master or blogs 🙂 I really appreciate all your responses and insight. I just got into modules this week and wanted to make sure i understand what you mean when you say, be sure to load a sub-module as a child of the module. Can you give an example?

    Like, I current have a Flex Application that I am calling the Shell, then I use the to load module when the user clicks a button. So, say I want to then have a sub-module to the first module loaded, is just adding another in the mxml of the first module considered a child?

    As far as I know it should be a child, but just wanted to clarify in case I was missing some special syntax somewhere. I’m setting the moduleLoader.url to the module swf and then calling moduleLoader.loadModule(), and that creates the moduleLoader.child just file for me. Thanks again!

  49. Alex.G says:

    Hello fellow Alex,

    Does it matter whether the cleanup (removing references, focus, etc) happens before or after calling info.unload ?

    • Alex Harui says:

      In theory, it shouldn’t matter. Once all references have been released, it can get GC’d and unload