具有 0 条路径的 Flex 游荡对象

Posted

技术标签:

【中文标题】具有 0 条路径的 Flex 游荡对象【英文标题】:Flex loitering objects with 0 paths 【发布时间】:2011-05-26 17:57:34 【问题描述】:

我的应用程序泄漏了一个名为 GraphViewer 的可视化组件。每次用户更改图表时,都会创建一个新查看器,并将旧查看器从舞台上移除并丢弃。然而,内存似乎泄漏了。当我使用 Flex 分析器跟踪游荡对象时,它表明 GraphViewer 实例确实泄漏,但是当我检查游荡查看器的对象引用时,我发现所有这些(除了一个)都有 0 个到 GC 根的路径。

我在 GC 之后拍摄内存快照,然后更改图表(创建新查看器)N 次。然后我进行 GC,拍摄另一个快照并查看游荡对象。我看到 N 个 GraphViewer 对象徘徊,但其中 N-1 个实际上有 0 条路径,只有一个有任何实际引用它的东西。

当无法从 GC 根访问对象时,为什么 Flex 分析器将对象显示为游荡? Flex 分析器可靠吗?

【问题讨论】:

【参考方案1】:

首先,当新数据到达时,为什么需要创建组件的新实例?好像有点浪费。重用一个实例比创建一个新实例要好。

其次,没有代码很难回答您的问题,但视图组件保留在内存中的原因通常是因为有人仍然对它有引用,或者没有正确清理事件侦听器。

最后,GC 中有一个已知的错误已经有一段时间了(尽管我最近没有测试过;我可以重现大约一年了),其中大内存“孤岛”(想想一个非常大模块)不会正确清理,因为 GC 的往返算法不会认为它与其余部分断开连接。为了缓解这种情况,您可能希望实现一个 IDisposable 接口,在该接口中,您的“父”视图在从阶段移除之前调用销毁函数(然后在整个组件中传播,并且它的子组件也将被销毁)。

祝你好运。

【讨论】:

要重申并专注于 J_A_X 的部分答案,请检查您的事件侦听器。对于您 addEventListener 的每个实例,请确保在销毁对象之前调用 removeEventListener。在我的项目中,这往往是最常见的泄漏源。 我描述的情况是对实际项目的简化。这是一个非常复杂的 UI,包含数百个递归组件。不想在这里谈这个。但最重要的是,每当模型更改时,我实际上是在使用 Remove 事件来清理对这些对象的引用。如果这是一个 GC 错误,那么我想我别无选择,只能重用实例。但是手动释放项目中的所有引用非常容易出错并且不能成为答案......(GC到底是为了什么,对吧?)。所以我只是想知道是否有人遇到过这种 0 路径现象。 另外,查找所有 addEventListeners 并确保为每个调用 removeEventListener,即使未引用这些项目,也不会解决所有基于 mxml 的侦听器的问题(或者您是否建议我以某种方式也释放那些)?我只是拒绝相信 Flash GC 如此糟糕.. :) GC是用来清理的,但不能清理不好的开发。为什么每次都要创建一个新实例?这是浪费和无用的,特别是如果你的组件很重(听起来像这样)。在我看来,您的问题不仅仅是“让 GC 处理它”,而是错误的架构/代码。没有万无一失的 GC。 基于 MXML 的侦听器在从舞台上移除后会自动清理。同样,我从未见过与该特定问题有关的问题。如果有的话,那是你的代码有问题。

以上是关于具有 0 条路径的 Flex 游荡对象的主要内容,如果未能解决你的问题,请参考以下文章

如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象

RestKit 0.20 嵌套对象映射(对象树的路径不同)

可能在 Canvas 而不是 Chart 对象上有 Flex 数据提示?

具有动态内容的 Flex 网格

Restkit 返回具有 0 个键值对的对象数组

Flex3 Datagrid:标志上的自定义行