Actionscript 3 air应用程序中的内存优化

Actionscript 3 air应用程序中的内存优化,actionscript-3,flex4,air,Actionscript 3,Flex4,Air,我有一个简单的air应用程序,部署在服务器上。它所做的只是每5分钟向一个网页发出一个httpService请求。出于某种原因,它一开始的内存利用率为25MB(任务管理器),每天都会增加1MB左右。我不明白为什么它会吸吮记忆。我有一个eventlistener用于初始化应用程序中的计时器。 我读过几篇关于内存优化和air应用程序开发最佳实践的文章。他们说你应该在事件侦听器启动后删除它们。但如果我这样做,计时器在触发一次后将不会触发任何函数。 有人能分享一下优化这个的想法吗? 以下是我的代码片段:

我有一个简单的air应用程序,部署在服务器上。它所做的只是每5分钟向一个网页发出一个httpService请求。出于某种原因,它一开始的内存利用率为25MB(任务管理器),每天都会增加1MB左右。我不明白为什么它会吸吮记忆。我有一个eventlistener用于初始化应用程序中的计时器。 我读过几篇关于内存优化和air应用程序开发最佳实践的文章。他们说你应该在事件侦听器启动后删除它们。但如果我这样做,计时器在触发一次后将不会触发任何函数。 有人能分享一下优化这个的想法吗? 以下是我的代码片段:

private var service:HTTPService; 

private function init() :void { 
service = new HTTPService(); 
service.method = "GET"; 
service.url = serviceUrl; 
service.addEventListener(ResultEvent.RESULT, httpResult);
service.addEventListener(FaultEvent.FAULT, httpFault); 
callhttpService(); 
pingTimer = new Timer(pingInterval,0);
pingTimer.addEventListener(TimerEvent.TIMER,timer_doth­is);

} 

private function callhttpService():void { 
  service.send();
} 

private function timer_dothis(evt:TimerEvent):void { 
  callhttpService(); 
}

基本上,您无法在Flash/AIR中管理内存。内存由VM使用MMgc进行内部管理

因此,基本上,您开始阅读的内容是正确的(某种程度上),您需要完全取消对对象的引用,以确保垃圾收集器在下一个过程中拾取它们,其频率由VM内部根据VM运行的系统的性能确定。至于计时器事件,我不会说您需要一次又一次地删除/重新添加侦听器,但可能需要停止事件回调中的事件传播(例如stopImmediatePropagation()

()

但是要做的就是阻止事件在其他任何地方被处理或冒泡,我一秒钟也不认为这是内存泄漏的原因。很可能在某个地方,你正在创建和销毁对象,或者创建它们并简单地丢弃它们,而实际上却没有正确地销毁它们。下面是一篇关于跟踪flash/AIR中泄漏的文章的链接。它从actionscript方面很好地解释了整个过程的工作原理:


如果你浏览了那篇文章,然后检查你的代码,并将其缩小到你认为的问题,但不确定,用一些代码片段更新你的问题,我将更新我的答案以解决你发布的任何问题。:)

很明显,应用程序中存在内存泄漏。当然,在处理事件后取消订阅是非常有用的建议。与事件相关的内存泄漏是常见问题之一

你的情况如何?你不应该取消订阅计时器事件,因为它仍在你的应用程序中使用。但请看一下您的HTTP调用相关代码。你如何打电话?也许您在每次调用时都会创建新的请求对象,并且在使用它们取消订阅相应事件后不会清理内存

不管怎么说,没有代码,我们就不能给你一个解决特定问题的建议。只有建议


如果您放弃查找有问题的代码,您可以使用探查器,它是FlashBuilderPremium的一部分。它可以帮助您。

计时器中接收到的事件可能是泄漏原因的一个实例是,如果您要捕获并保存事件中的对象引用。例如,您引用了e.currentTarget,但创建了对事件当前调度程序(当前目标)的本地或类级别引用。然后,flash可能会保留该事件的副本,因为您通过自身间接引用它的父级或调度程序。不确定,只是一个想法,但是需要一些测试用例来证明/反驳。谢谢。我将浏览您提供的链接。同时,这里是我代码的一部分:私有var服务:HTTPService;私有函数init():void{service=new-HTTPService();service.method=“GET”;service.url=serviceUrl;service.addEventListener(ResultEvent.RESULT,httpResult);service.addEventListener(FaultEvent.FAULT,httpFault);}谢谢。我将浏览您提供的链接。同时,这里是我代码的一部分:私有var服务:HTTPService;私有函数init():void{service=new-HTTPService();service.method=“GET”;service.url=serviceUrl;service.addEventListener(ResultEvent.RESULT,httpResult);service.addEventListener(FaultEvent.FAULT,httpFault);callhttpService();pingTimer=new Timer(pingInterval,0);pingTimer.addEventListener(Timer.Timer,Timer_dothis);}私有函数callhttpService():void{service.send();}私有函数timer_dothis(evt:TimerEvent):void{callhttpService();}@CodeQrius-你真的应该把你的代码放在上面的问题中,因为它将被格式化,甚至在那里突出显示。没有人喜欢阅读未格式化的代码。另外,这与您的总体问题有关,而不仅仅与您对AscSys的回答有关。同意。请编辑/更新您的问题,并在问题本身中发布此代码。:)对HTTP请求的良好调用。CodeQrius可能会发出类似myRecycledLoader.load(newUrlRequest(url))的请求;或者在每次调用中创建新的本地加载程序和请求。这是最好的建议,没有任何关于问题是什么的代码+1:)谢谢。请参阅下面我的代码片段。如果您对它有任何意见。只需编辑您的原始问题,并请使用代码格式化程序将您的代码添加到那里。谢谢即使应用程序有一些漏洞,若它们很小,你们可以每隔几个小时/天/周重新启动应用程序,而不是修复它们。看起来不错。那么结果和错误处理程序呢?