AS3:会造成内存泄漏吗?

问题描述:

public class MyButton extends Sprite 
{  
    public function MyButton(defaultHandler:Function)  
    {  
     addEventListener(MouseEvent.CLICK, defaultHandler);  
    } 
} 

//主类AS3:会造成内存泄漏吗?

var myButton:MyButton =new MyButton(someFunction); 
addChild(myButton) 

removeChild(myButton); 
myButton = null; 

IE我从内到我的Button类添加一个匿名鼠标点击事件处理函数,它在建造时,并没有明确删除它时,它从台上撤下来,并无效。

此对象是否符合垃圾回收器的条件,是否会造成内存泄漏?或者因为事件监听器只引用一个本身被删除的对象,它也会被删除?

Button实例上的事件侦听器将阻止垃圾收集,除非您专门删除侦听器,或者指示侦听器将成为弱引用。

addEventListener(MouseEvent.CLICK, defaultHandler, false, 0, true); 

最后一个参数true,传递的参数useWeakReference。从docs

将useWeakReference:布尔(默认值= false) - 确定的 参考听者是否是强还是弱。强引用(默认为 )会阻止您的侦听器被垃圾收集。弱 参考没有。

+0

当设置一个监听器是软弱的,去除的责任是转移到垃圾收集器。你不应该信任GC,因为它大多是随机的,所以可能需要一段时间。弱听者是懒惰的开发人员,他们不负责清理自己的代码。唯一的例外可能是舞台上的事件监听者,但你应该总是自己移除监听者。 –

+1

同意@MarkKnol,我总是明确地删除它们。这就是说,这不是OP所要求的。 – sberry

+0

我发现这是一个稍微不同的场景,但有类似的问题: http://stackoverflow.com/questions/8471578/would-this-code-cause-memory-leakage 其中有一个引用: “事件侦听器不会自动从内存中移除,因为只要派发对象存在**,垃圾收集器就不会删除侦听器**(除非useWeakReference参数设置为true)。” - 所以根据这个,如果监听器引用的对象不再存在,它不应该**持续存在并且不应该引起泄漏 - 任何人都可以证实这一点吗? –

虽然@ sberry的答案中的点是完全有效的,但仔细看看在这种情况下哪些对象具有相互引用。

如果主类是围绕用于应用的生命周期,没有内存泄漏

主要类有它实例化到按钮类的引用。

Button类具有对来自事件处理函数的主类的引用。

主类将其对该按钮的引用归零。

此时,有不再提及按钮。按钮可以并将被垃圾收集。

如果主类真的是应用程序的整个生命周期,那就没有问题了。如果主类消失,但其中一个按钮对象仍然存在,然后你有内存泄漏(按钮保持对main的引用,并且main不能被垃圾收集)。

PS:我并不是在反对删除事件侦听器时或使用弱引用,我做这两个做法自己尽可能:)

+0

是的这就是我所说的,如果对象本身不再存在,那么理论上它的事件听众也不应该这样做。 - 任何人都可以证实这一点? –

+0

[这是一篇来自Adobe的文章](http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html),它支持我说的话。垃圾收集以两种方式工作:引用计数(快速),然后“标记和扫描”捕获具有循环引用的东西(计数永远不会为0)。在你的例子中,当你这样做时,按钮的引用计数变为0:'removeChild(myButton); myButton = null;'该按钮符合垃圾回收的条件,但不能保证什么时候会发生。 –

+0

只是为了澄清和回答你的评论中的具体问题:当你在按钮中使用'addEventListener()'时,该按钮基本上将该事件映射到一个函数(在这种情况下,在你的主类中定义)。所以,当按钮变成g/c'd时,这个映射会随之而来,事件监听器可以被认为不再存在。在添加它们时删除监听器和/或使用弱引用仍然是一个好习惯:) –