2011-04-15 22 views
0

我有一个简单的空气应用程序部署在服务器上。它所做的只是每5分钟向网页发出一次httpService请求。出于某种原因,它开始时的内存使用率为25MB(任务管理器),并且每天增加大约1MB。我无法弄清楚为什么它会吮吸内存。我有一个应用程序初始化定时器的eventlistener。 我已阅读一些关于内存优化和空气应用程序开发最佳实践的文章。他们说你应该在他们解雇后删除事件监听器。但是如果我这样做了,定时器在触发一次后不会触发任何功能。 任何人都可以分享优化这个想法吗? 这里是我的代码片段:空气应用程序中的内存优化

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(); 
} 
+0

即使应用程序有一些泄漏,如果它们太小,您可以每隔几个小时/天/周重新启动应用程序,而不是修复它们。 – alxx 2011-04-16 19:30:01

+0

看起来不错。结果和错误处理程序如何? – Constantiner 2011-04-16 20:13:08

回答

1

基本上你不能管理在Flash/AIR内存。内存由VM使用MMgc进行内部管理。

https://developer.mozilla.org/en/MMgc

所以基本上你已经开始读的东西是正确的(那种),您需要取消引用的对象完全以确保垃圾收集挑选他们在它的下传,其频率由VM根据VM运行的系统的性能在内部确定。至于定时器事件,我不会说你需要反复删除/重新添加监听器,但也许可以在事件回调(e.stopImmediatePropagation())中停止事件传播。

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/Event.html#stopImmediatePropagation()

但所有这一切要做的是被处理或起泡其他地方停止事件,我不为第二想象这是你的内存泄漏的原因。这很可能是你创建和销毁对象的地方,或者是创建它们并在没有真正摧毁它们的情况下丢弃它们。以下是关于在flash/AIR中跟踪泄漏的文章的链接。它解释了这整个事情从ActionScript端是如何工作的非常好:

http://divillysausages.com/blog/tracking_memory_leaks_in_as3

如果通过这篇文章运行,然后检查你的代码,它缩小到什么你认为是问题,但不能确定,用一些代码片段更新你的问题,我会更新我的答案,以解决你发布的任何问题。 :)

+0

也许在定时器中收到的事件可能是泄漏原因的一个实例是如果您要从事件捕获并保存对象引用。例如,你引用了e。currentTarget,但创建对事件当前调度器(当前目标)的本地或类级别引用。然后,也许flash将保留该事件的副本,因为您通过自己间接引用它的父代或调度程序。不确定,只是一个想法,但需要一些测试案例来证明/反驳。 – 2011-04-15 22:31:25

+0

谢谢。我会通过你提供的链接。同时这里是我的代码的一部分: 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); } – CodeQrius 2011-04-15 22:48:02

+0

谢谢。我会通过你提供的链接。同时这里是我的代码的一部分: private var service:HTTPService; ():void { service = new HTTPService(); service.method =“GET”; service.url = serviceUrl; service.addEventListener(ResultEvent.RESULT,httpResult); service.addEventListener(FaultEvent.FAULT,httpFault); callhttpService(); pingTimer =新的计时器(pingInterval,0); \t \t \t \t pingTimer.addEventListener(TimerEvent.TIMER,timer_dothis);} 私有函数callhttpService():无效{ \t service.send();} 私有函数timer_dothis(EVT:TimerEvent):无效{ callhttpService() ; } – CodeQrius 2011-04-15 22:54:43

1

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

你的情况你不应该退订计时器事件,只要它仍然在你的应用程序中使用。但看看你的HTTP调用相关的代码。你如何进行呼叫?也许你在每次调用时都会创建新的请求对象,并在使用它们取消订阅相应事件后不清除内存?

无论如何没有代码,我们不能给你一个解决特定问题的建议。只有建议。

如果您放弃查找有问题的代码,则可以使用属于Flash Builder Premium的分析器。它可以帮助你。

+0

良好的HTTP请求调用。 CodeQrius可以让这些请求像myRecycledLoader.load(新的URLRequest(url));或在每次调用中创建新的本地加载器和请求。这是最好的建议,没有任何代码问题是什么。 +1 :) – 2011-04-15 22:33:47

+0

谢谢。请参阅下面的代码片段。如果你有任何意见。 – CodeQrius 2011-04-15 22:55:23

+0

只需编辑你原来的问题,并请使用代码格式化程序在那里添加你的代码。谢谢! – Constantiner 2011-04-15 22:58:58