首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > flex >

Flex 施用内存泄露的分析与诊断

2012-11-25 
Flex 应用内存泄露的分析与诊断即使把 b 置为 null,只要 a 对象没有被回收,b 也不会被回收,从而导致内存泄

Flex 应用内存泄露的分析与诊断

即使把 b 置为 null,只要 a 对象没有被回收,b 也不会被回收,从而导致内存泄露。通过弱引用方式可以避免这种内存泄露,在后面的章节会有详细描述。

选项“Enable performance profiling”是用做性能调优的,主要用来找到响应时间的瓶颈。在做内存调试时,将这一项勾掉。 选项“Generate object allocation stack traces”选项可以跟踪对象创建的整个过程,这个功能非常消耗系统资源,在调试的初期,目的是找到内存泄露的对象,而不关心它的创建过程,因此先不要选择该项。

配置完毕,点击 Resume 按钮继续执行。

几秒钟之后,Profiler 工具开始运行,如下图所示:


图 4. Profiler 运行主界面
Flex 施用内存泄露的分析与诊断

这里简要介绍一下和内存调试相关的按钮的功能:

图 5 中 1“Run Garbage Collector”,点击该按钮,会强制执行一次内存回收。

图 5 中 2“Take Memory Sanpshot”,在运行的任何时刻,点击该按钮,系统首先会自动执行一次强制内存回收,然后捕获一帧内存快照,作为当前正在运行的应用的子对象,如下图所示:


图 6. 捕获内存快照
Flex 施用内存泄露的分析与诊断

双击这帧内存快照,会在下部窗口打开一个页签,显示该内存快照中的对象,包括对象所在的包,实例数目和百分比,所占内存和百分比,如下图所示:


图 7. 内存快照中的对象
Flex 施用内存泄露的分析与诊断

图 5 中 3“Find Loitering Objects”,找出“游荡对象”。该按钮需要同时选中两帧内存快照(按住 Ctrl 键点选内存快照)才有用,如下图所示:


图 8. 选中两帧内存快照
Flex 施用内存泄露的分析与诊断

它的作用是通过对比两帧内存快照,找出在后一帧内存快照中存在而在前一帧内存快照中 不存在的对象。在某些特定的场景中,该功能能够迅速找到内存泄露的对象。

每当用户点击“Change”按钮时,就会随机产生一个 4 位数字替换原来的数字。该程序在用户每次点击按钮后都会导致内存的增加,我们怀疑这个程序存在内存泄露。启动 Profiler 工具,用户每点击一次“Change”按钮,我们就捕获一帧内存快照,连续做 3 次,我们对比一下这 3 帧快照,如下图所示:


图 10. 3 帧内存快照对比
Flex 施用内存泄露的分析与诊断

通过对比,我们发现 NumberChangeLabel 的实例数目随着用户的每次点击都会增加,并且不会被回收,因此断定是 NumberChangeLabel 导致了内存泄露。双击最后一帧内存快照中的 NumberChangeLabel 对象,会打开“Object References”页签,显示这 4 个实例被哪些对象引用,如下图所示:


图 11. 对象引用图
Flex 施用内存泄露的分析与诊断

表中的 4 条数据代表这帧内存快照中有 4 个 NumberChangeLabel 实例,每个实例后面括号中的数字,比如(7),代表了有多少个引用指向这个实例。点击“+”号,逐项展开,如下图所示:


图 12. 分析对象引用
Flex 施用内存泄露的分析与诊断

我们发现绝大部分是对象自身或者对象的子元素对该对象的引用,这种引用不会产生内存泄露。而有一项 DetectmemoryLeak 的 arr 属性对 NumberChangeLabel 的引用是外部引用,也正是因为这个引用导致 NumberChangeLabel 不能被回收。检查相关的源代码:


清单 4. DetectMemoryLeak.mxml

点击“Popup a dialogue”弹出对话框,如下图:


图 14. 中间状态
Flex 施用内存泄露的分析与诊断

点击“OK”按钮关闭对话框之后,到达终止状态。在初始状态和终止状态各捕获一帧内存快照,选中两帧快照点击“Finding Loitoring Objects”按钮,打开“Loitoring Objects”页签,如下图:


图 15. 游荡对象
Flex 施用内存泄露的分析与诊断

产生了很多游荡对象,别担心,大部分对象都是由一个或几个高层对象产生的,找出产生内存泄露的高层对象就能解决问题。我们发现游荡对象“LeakDialogue”是程序中的一个用户自定义对话框,它可能是产生了内存泄露的根源。双击这个条目打开“Object Reference”页签,如下图:


图 16. 游荡对象 LeakDialogue 的引用
Flex 施用内存泄露的分析与诊断

点击“+”号逐项展开,通过分析发现,LeakDialogue 的 leakHandler 方法被全局对象 systemManager 的 listener21 引用导致了内存泄露,检查程序发现问题果然出在 systemManager 的事件监听环节:


清单 5.LoiteringMemoryLeak.mxml

另外,自引用方式 a.addEventListener("Leak", this.leakHandler); 子对象对父对象的引用方式 children.addEventListener("Leak", parent.leakHandler); 都不会产生内存泄露。

    对于自定义组件要尽量早地做内存泄露的测试。如果等到集成之后再做整体的测试,系统的复杂度变高,组件的层次和关联过于复杂,要定位到问题的根源,是一件非常费时费力的事。 Flex 还是一门比较新的技术,Flex 框架本身也存在一些内存泄露的问题。好在 Adobe 已经将它的 Bug 系统公开,开发人员可以到 http://bugs.adobe.com/去查找已经存在的内存泄露问题和一些官方的解决方案,相信对解决内存泄露问题会有所帮助。
描述名字大小下载方法示例代码sourceCode.zip600KBHTTP

热点排行