【问题标题】:Debugging FLEX/AS3 memory leaks调试 FLEX/AS3 内存泄漏
【发布时间】:2010-10-14 11:39:47
【问题描述】:
我有一个相当大的 Flex & Papervision3D 应用程序,它可以不断地创建和销毁对象。它还加载和卸载 SWF 资源文件。在运行 SWF 时,它会慢慢消耗内存,直到播放器发出 2GB 左右的声音。显然,我很确定我放弃了对我不再想要的实例的引用,并期望 GC 会完成它的工作。但是我花了很长时间弄清楚问题出在哪里。
我已经尝试使用分析器及其选项来捕获内存快照等 - 但我的问题仍然是回避。我认为使用调试 Flash 播放器也存在已知问题?但我也不喜欢使用发布版本。
您如何使用 FLEX/AS3 跟踪内存泄漏问题?有哪些定位消费的策略、技巧或工具
【问题讨论】:
标签:
apache-flex
actionscript-3
debugging
memory-leaks
papervision3d
【解决方案1】:
我通常在我创建的每个类中实现一个清理方法(因为 AS 没有析构函数)。我注意到 GC 的主要问题是事件侦听器。除了直接说的话,还要尽量避免匿名侦听器函数(因为你不能明确地删除它们)。以下是一些您可能会觉得有用的链接:
【解决方案2】:
我偶然发现了一些解释如何在 Flex Builder 中使用 Flex Profiler 的东西,这对我调试内存泄漏有很大帮助。我肯定会建议尝试一下。它非常易于使用。我在分析我的应用程序时发现的一些事情:
避免使用集合(至少 LARGE 集合)作为值对象的属性。我的 Cairngorm 应用程序中有几种类型的值对象类,每个都有一个“子”属性,即 ArrayCollection,用于过滤。在分析时,我发现这些是我最大的内存消耗者之一,因此我更改了我的应用程序,将“parentId”存储为int 并使用它进行过滤。使用的内存被大幅削减。像这样的:
老办法:
public class Owner1
{
public var id:int;
public var label:String;
public var children:ArrayCollection; // Stores any number of Owner2 Objects
}
public class Owner2
{
public var id:int;
public var label:String;
public var children:ArrayCollection; // Stores any number of Owner3 Objects
}
public class Owner3
{
public var id:int;
public var label:String;
}
新方式:
public class Owner1
{
public var id:int;
public var label:String;
}
public class Owner2
{
public var id:int;
public var label:String;
public var parentId:int; // Refers to id of Owner1 Object
}
public class Owner3
{
public var id:int;
public var label:String;
public var parentId:int; // Refers to id of Owner2 Object
}
我还建议在不再需要事件侦听器时删除它们。
【解决方案3】:
由于此类问题,我开发了一个开源库,可帮助监控您在任何给定时间运行的所有事件。它真的很容易实现,我在 10-15 分钟内重构了项目,将它们转换为使用我开发的 EventController。
基本上,对于您的场景,我会遍历所有事件并将它们替换为:
obj.addEventListener(...);
到:
EC.add(obj,...);
其余部分与注册事件相同,然后使用 EC.log() 让您在任何时候都可以轻松查看所有事件;
所有详细信息和文档都在我的网站上,我很想知道这是否对您有帮助,以及您是否开始使用它。如果您有任何好的或不好的反馈,请随时发布,我会调查它!
该网站是:
http://fla.as/ec/
【解决方案4】:
如果您的内存泄漏呈指数增长,则可能意味着 GC 未能完成其工作。看看你的代码,看看哪里可以减少对象的引用计数(通过将它们设置为null)。使事件处理程序变弱。并重新配置文件。