【问题标题】:Garbage collection question (display list + actionscript)垃圾回收问题(展示列表+actionscript)
【发布时间】:2011-09-01 14:21:48
【问题描述】:

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

  1. 没有任何事件侦听器附加到该对象
  2. 我向那个对象添加了显示对象? (obj.addChild(whatever) --> 当我从显示列表中删除对象时,我需要删除“whatever”还是多余的?)
  3. 与该对象关联的任何实例变量 - 我需要将它们设为空吗?

【问题讨论】:

    标签: actionscript-3 actionscript


    【解决方案1】:

    如果您删除对父对象的所有引用,则无需删除其子 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,所以它不会被垃圾回收。父 obj 对象也不会被垃圾回收,因为 obj2.parent 引用它。如果obj 是我们的黑匣子,那么我们对obj2 的引用指向黑匣子内部!

    因此,在清理对象时清空并删除对象可能是一种很好的做法,尤其是在不清楚的混乱情况下。如果您删除它们,您将永远是安全的,但您最终可能会编写不必要的代码。

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

    【讨论】:

      猜你喜欢
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 2011-02-23
      • 2011-06-03
      相关资源
      最近更新 更多