有人可以发布一个as3代码示例(特别是包含事件监听器),这可能是一个可能泄漏内存的简单示例...也希望你能解决所显示的问题吗?
问题是:在AS3事件监听器中泄漏内存的简单示例是什么?如何解决?
答案 0 :(得分:7)
public class MySprite extends Sprite {
public function MySprite() {
if(stage) {
init();
} else {
addEventListener(Event.ADDED_TO_STAGE,init);
}
}
private function init(e:Event = null):void {
stage.addEventListener(Event.RESIZE,handleStageResize);
}
private function handleStageResize(e:Event):void {
// do some processing here.
}
}
其他地方:
var mySprite:MySprite = new MySprite();
someHolder.addChild(mySprite);
现在,如果稍后你删除mySprite,它仍会在内存中徘徊,因为它已经在init()方法中向舞台添加了自己(或对它自己的引用)。
在这种情况下,避免这种情况的最佳方法是在从显示列表中删除mySprite时删除添加到舞台的侦听器。
private function init(e:Event = null):void {
addEventListener(Event.REMOVED_FROM_STAGE,cleanUp);
stage.addEventListener(Event.RESIZE,handleStageResize);
}
private function cleanUp(e:Event):void {
stage.removeEventListener(Event.RESIZE,handleStageResize);
}
我确信其他人会在将监听器添加到舞台时告诉您使用弱引用,但无论如何都应该删除听众。如果不这样做,当您从显示列表中删除mySprite并且没有其他参考时,将有资格使用GC,并最终将从内存中删除。但在此之前,handleStageResize()中的代码将继续执行。
答案 1 :(得分:4)
我将跟进@Juan的答案 - GC需要从头开始考虑作为应用程序设计的一个关键方面。如果您创建了一个对象,则必须知道对它的每个引用,并删除每个引用并使其无效以正确标记@。如果你在数组中引用该对象,那么,如果你在一个监听器中引用它,那么它就会计数,如果你通过一个局部变量引用它,那么它也很重要(虽然只是在函数的生命周期内),如果只是在显示列表,绝对有效,等等。
我甚至在添加之前编写我的删除侦听器语句以确保。
我几乎总是会为任何对象编写一个公共destroy()方法来处理内部对象层次结构(父对子调用destroy,后者在任何子对象上调用destroy等)。只是删除/清空父级而不对每个孩子这样做是GC管理不善。
如果你真的有任何担心mem泄漏的问题,请追踪System.totalMemory以确保:
var mem:String = Number( System.totalMemory / 1024 / 1024 ).toFixed( 2 ) + ‘Mb’;
trace( mem ); // eg traces “24.94Mb”
主要是 - 只是对它有条不紊 - 它不是火箭科学,但你必须要小心。
干杯 -
@即使你这样做,flash也会自己决定何时进行扫描。我们能做的最好的事情是确保一个对象被正确标记并且信任它将被有效地处理。
答案 2 :(得分:0)
我不打算发表这样的例子,但我会解释一下。你在这里描述了两种情况。
AS3以不同方式处理内存和处理器操作。
当创建和销毁许多对象时发生内存泄漏。这些对象在有引用时泄漏内存,并且在销毁对象时销毁对象 - 因此留下未使用对象的内存块=泄漏。
当你有许多方法相互引用而没有'关闭循环'时,会发生处理器溢出。