Flex ModuleLoader 组件导致内存泄漏。如何正确卸载模块?
该应用程序太大,无法在此描述,但我可以告诉您,我有多达 20 个或更多模块可供客户端随时使用。如果我继续加载一个又一个屏幕,我的应用程序可能会占用 500MB 甚至更多。
我用来加载和卸载模块的脚本是:
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.");
}
加载模块的容器:
<s:BorderContainer width="98%" height="98%" includeIn="mainState" styleName="bcModuleLoader" top="100">
<s:layout>
<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>
每当我单击我认为与此处发布无关的菜单选项时,都会调用 createModule 函数。总而言之,这就是我现在让它工作和泄漏的一切:S
这是官方的 unloadModule 函数,我认为,从它的外观来看,内存应该很好地分配给这个东西,我的意思是,看!它删除所有事件监听器和子对象。为什么我的内存在卸载时保持不变,而当我打开新模块时加载更多内存?!啊啊!
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;
}
}
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>
<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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用的是 Flex 4.5,请尝试改用
。更多详细信息:此处
If you are using Flex 4.5, try to use
<s:ModuleLoader/>
instead.More details : here
来自这篇文章:
使用
HierachicalData
时通过AdvancedDataGrid
,该控件通过使用IHierarchicalCollectionView
界面来跟踪分层和分组数据。该接口有一个openNodes
属性,其中包含一个对象数组,这些对象表示当前在 AdvancedDataGrid 中打开的数据提供程序的节点。如果您用新的数据提供程序替换数据提供程序,
AdvancedDataGrid
控件不会清除openNodes
属性。由于openNodes
属性包含对旧数据提供程序中对象的引用,因此无法通过垃圾回收从内存中删除这些对象。为了确保可以从内存中删除旧的数据提供程序,请在替换数据提供程序时使用事件处理程序清除openNodes
属性。将事件侦听器添加到数据提供程序的
CollectionEvent.COLLECTION_CHANGE
事件以清除 openNodes 属性。From this article:
When using
HierachicalData
with anAdvancedDataGrid
, the control keeps track of hierarchical and grouped data by using theIHierarchicalCollectionView
interface. The interface has anopenNodes
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 theopenNodes
property. Because theopenNodes
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 theopenNodes
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.