我注意到在使用AS3时有些危险 - 某些对象(即DisplayObjects / MovieClips)往往会保留在内存中,甚至在删除所有对它们的引用后执行操作。
我使用Flash CS 5.5
和Flash Builder 4.6
。
从文档类中删除所有引用(包括removeChild(...))之后,某些对象似乎仍然活着。
这个问题可能有点宽泛 - 但我想要了解的是我该怎样做以确保垃圾收集器拾取了一个对象?
更重要的是,我如何从GC获得某种反馈,表明某个物体已被破坏? (例如,控制台消息)
提前致谢。
答案 0 :(得分:3)
从舞台中删除对象,删除事件侦听器并设置对null
的所有引用应该足够了 - GC将在下次执行时将其拾取。
跟踪所有引用是很乏味的(并且记住这包括事件侦听器,除非你将useWeakReference
设置为true),如果你没有标准的方法来做这件事。建议在每个类中都有一个“析构函数”函数,它可以在不再需要对象时清理所有变量和事件监听器。
您也可以将这些与事件结合起来 - 我认为最好在init()
上执行Event.ADDED_TO_STAGE
函数,在Event.REMOVED_FROM_STAGE上执行destroy()
函数。这样,您就可以为舞台对象定义明确的生命周期,如果确保destroy()
方法停止所有动画和声音,则删除所有子节点和事件侦听器,并将所有成员变量字段设置为null
,你可以肯定的是,不再有任何可能产生不良副作用的活动。
顺便说一句 - 如果您实际上注意您已删除的对象的任何活动,那么某些引用肯定仍然完好无损 - 您还能告诉我们其他什么?
但是,没有办法知道GC究竟何时会获取一个丢弃的对象 - 这是由VM管理的,并且在完成后你不会收到消息。考虑何时释放记忆不应该是你的责任 - 毕竟,这正是垃圾收集者的发明!
如果你养成了自己清理的习惯,你的程序 将不可避免地变得更稳定,消耗更少的内存并最终表现更好。这就是重要的事情。
答案 1 :(得分:2)
@weltraumpirat肯定有一些好主意并创建初始/销毁周期,因为工作实践是一个很好的采用。您可能还需要考虑其他问题。
创建新对象可能会耗费CPU,因此使用毯式init / destroy方法可能不是最佳方法,具体取决于您的应用实际执行的操作。您可能需要考虑创建一个对象池并在整个应用程序中回收它们。
这是一篇很棒的文章和工具,可让您跟踪应用中的对象,以便在任何时间点查看哪些对象仍然可以引用它们。
http://divillysausages.com/blog/tracking_memory_leaks_in_as3