垃圾收集问题(显示列表+动作脚本)

时间:2011-09-01 14:21:49

标签: actionscript-3 actionscript

如果我添加一个将MovieClip或Sprite扩展到舞台的对象,并从舞台中删除该对象,在以下情况下是否需要destroy方法:

  1. 没有任何事件监听器附加到该对象
  2. 我在那个对象上添加了显示对象? (obj.addChild(无论如何) - >当我从显示列表中删除对象时,是否需要删除“无论什么”?或者这是多余的?)
  3. 与该对象关联的任何实例变量 - 我是否需要将这些变量归零?

1 个答案:

答案 0 :(得分:2)

如果删除对父对象的所有引用,则不必删除其子DisplayObject,或者使其成员变量为空,假设没有对这些子对象的外部引用。

Flash使用“标记扫描”垃圾收集器。为了确定哪些对象符合垃圾收集的条件,Flash从最顶层的Stage元素开始,遍历它找到的任何引用,标记对象。任何未标记的对象都无法访问,并且有资格进行垃圾回收。

想象一个黑盒子对象。如果删除对此框的所有引用,则它将有资格进行垃圾回收。现在想象一下,这个黑盒实际上里面有很多子对象。尽管父黑盒子和子对象之间可能存在引用,但它并没有改变黑盒本身不可访问的事实,因此所有这些“内部”引用都无关紧要。这些对象将有资格进行垃圾回收。你已经从树中剪断了分支,即使分支本身可能有许多分支和较小的分支。

这是一个简单的例子:

var obj:MySprite = new MySprite();
obj.foo = new Foo();
obj.addChild(new Sprite());
addChild(obj);

我们如何清理obj及其子组件?所有必要的是:

removeChild(obj);
obj = null;

现在obj无法访问,其子组件也是如此。他们都有资格进行垃圾收集。

但是,如果您对这些子对象有任何外部引用,则应该小心:

var obj2:Sprite = new Sprite();
obj.addChild(obj2);
obj = null;

即使我们排除了obj,我们也忘记了obj2,因此它不会被垃圾收集。父{4}}对象也不会被垃圾收集,因为obj引用它。如果obj2.parent是我们的黑匣子,那么我们对obj的引用指向黑匣子内部!

因此,在清理对象时清空和删除东西是一种好习惯,特别是在不清楚的混乱情况下。如果删除它们总是安全的,但最终可能会编写不必要的代码。

如果您想查看正在发生的事情,使用Flash Builder,FlashDevelop或FDT中的探查器工具来查看内存使用情况会很有帮助。如果要测试这些想法,可以使用System.gc()调用强制GC在调试模式下运行。