Flex ModuleLoader component causing memory leak. How can I unload Modules properly?
The application is too big to describe here, but I can tell you I have up to 20 modules or more that the client can use at any time. And if I go on loading screen after screen, my application can ocuppy 500MB and more.
The script that I use to load and unload modules is:
public function createModule(modulo:String):void {
if(moduleLoader != null){
moduleLoader.unloadModule();
//moduleLoader.url = null;
moduleLoader.url = "com/oss/facturable/components/" + modulo + "?version=" + model.configXML.versionApp;
moduleLoader.loadModule();
}
}
private function errorHandler(e:ModuleEvent):void {
Alert.show("No se ha podido cargar el modulo. Contacte al departamento técnico.");
}
The Container in which the module is loaded:
<s:BorderContainer width="98%" height="98%" includeIn="mainState" styleName="bcModuleLoader" top="100">
<s:layout>
<开发者_如何学Python;s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"/>
</s:layout>
<s:Scroller width="100%" height="100%">
<s:Group>
<mx:ModuleLoader id="moduleLoader" error="errorHandler(event)" width="100%" height="100%" horizontalAlign="center" verticalAlign="top" creationComplete="createModule('bandejaEntrada.swf')"/>
</s:Group>
</s:Scroller>
</s:BorderContainer>
The createModule function is called whenever I click on a menu option that I think is irrelevant to post here. All in all, this is everything I have for now to make it work and leak :S
This is the official unloadModule function, I thought, by the looks of it, that the memory should be well allocated with this thing, I mean, look! It removes all the eventListeners and child objects. How come my memory stays the same when unloading, and loads more memory on top of it when I open a new module?! Augh!
public function unloadModule():void
{
if (child)
{
removeChild(child);
child = null;
}
if (module)
{
module.removeEventListener(ModuleEvent.PROGRESS,
moduleProgressHandler);
module.removeEventListener(ModuleEvent.SETUP, moduleSetupHandler);
module.removeEventListener(ModuleEvent.READY, moduleReadyHandler);
module.removeEventListener(ModuleEvent.ERROR, moduleErrorHandler);
module.unload();
module.removeEventListener(ModuleEvent.UNLOAD, moduleUnloadHandler);
module = null;
}
}
If you are using Flex 4.5, try to use <s:ModuleLoader/>
instead.
More details : here
From this article:
When using HierachicalData
with an AdvancedDataGrid
, the control keeps track of hierarchical and grouped data by using the IHierarchicalCollectionView
interface. The interface has an openNodes
property contains an Array of objects that represent the nodes of the data provider that are currently open in the AdvancedDataGrid.
If you replace the data provider with a new data provider, the AdvancedDataGrid
control does not clear the openNodes
property. Because the openNodes
property contains references to objects in the old data provider, the objects cannot be removed from memory by garbage collection. To ensure that the old data provider can be removed from memory, use an event handler to clear the openNodes
property when you replace the data provider.
Add an event listener to the data provider’s CollectionEvent.COLLECTION_CHANGE
event to clear the openNodes property.
// Handle the colectionChange event.
private function removeOpenNodes(event:CollectionEvent):void
{
if(event.kind == CollectionEventKind.RESET)
IHierarchicalCollectionView(adg.dataProvider).openNodes = {};
}
精彩评论