我有以下代码:
private var xmlC:XMLListCollection = new XMLListCollection();
private var httpS:HTTPService = new HTTPService();
private var timer:Timer = new Timer(1000);
private var xmlData:XML;
private var xmlDataList:XMLList;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
httpS.url = "data.xml";
httpS.addEventListener(ResultEvent.RESULT, resultHTTP);
httpS.resultFormat="e4x";
httpS.send();
timer.start();
timer.addEventListener(TimerEvent.TIMER, updateXMLC);
}
private function updateXMLC(event:TimerEvent):void
{
xmlC.source = xmlDataList;
httpS.send();
}
private function resultHTTP(event:ResultEvent):void
{
xmlData = event.result as XML;
xmlDataList = xmlData.dg.rows.row;
}
“data.xml”有5000行,所以我需要在必要时清理它的踪迹。由于分析
,我发现了两个问题答案 0 :(得分:4)
在查看代码后会有任何内存泄漏,我对此持怀疑态度/好奇心,所以我为自己测试了代码。
您发布的代码实际上无法运行。我刚刚添加了最小值,让它像app tag和import语句一样运行(以及一个计数器标签,以查看http服务周期何时完成):
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="application1_creationCompleteHandler(event)">
<mx:Script>
<![CDATA[
import mx.rpc.http.HTTPService;
import mx.collections.XMLListCollection;
import mx.rpc.events.ResultEvent;
import mx.events.FlexEvent;
private var xmlC:XMLListCollection = new XMLListCollection();
private var httpS:HTTPService = new HTTPService();
private var timer:Timer = new Timer(1000);
private var xmlData:XML;
private var xmlDataList:XMLList;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
httpS.url = "data.xml";
httpS.addEventListener(ResultEvent.RESULT, resultHTTP);
httpS.resultFormat="e4x";
httpS.send();
timer.start();
timer.addEventListener(TimerEvent.TIMER, updateXMLC);
}
private function updateXMLC(event:TimerEvent):void
{
xmlC.source = xmlDataList;
httpS.send();
}
private function resultHTTP(event:ResultEvent):void
{
counter.text = Number(parseInt(counter.text,10)+1).toString();
xmlData = event.result as XML;
xmlDataList = xmlData.dg.rows.row;
}
]]>
</mx:Script>
<mx:Label id="counter" text="0" horizontalCenter="0" verticalCenter="0" fontSize="72"/>
</mx:Application>
好消息是代码中没有任何内存泄漏。在探查器中也没有任何游荡对象。
坏消息是你在应用程序中正在做的其他事情(这里没有发布的代码,无论出于何种原因而省略) - 这就是你有泄漏/游荡的对象。
您可以在附加代码的分析器中看到自己在http服务的前几个周期后内存不会增加。即随着时间的推移它不会继续抓住更多的记忆。 (顺便说一句,我提取的XML文件大约有8000行,超过1MB)。
如果你想发布更多代码,很高兴看得更远 - 但是现在想想这解决了这个谜。 ;)
以下是您正在做的事情的一些修复:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="application1_creationCompleteHandler(event)">
<mx:Script>
<![CDATA[
import mx.rpc.http.HTTPService;
import mx.collections.XMLListCollection;
import mx.rpc.events.ResultEvent;
import mx.events.FlexEvent;
[Bindable] private var xmlC:XMLListCollection = new XMLListCollection();
private var httpS:HTTPService = new HTTPService();
private var timer:Timer = new Timer(1000);
private var xmlData:XML;
private var xmlDataList:XMLList;
private var serviceRunning : Boolean = false;
private var currentData : String = '';
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
httpS.url = "data.xml";
httpS.addEventListener(ResultEvent.RESULT, resultHTTP);
httpS.resultFormat="e4x";
httpS.send();
timer.start();
timer.addEventListener(TimerEvent.TIMER, updateXMLC);
}
private function updateXMLC(event:TimerEvent):void
{
xmlC.source = xmlDataList;
if( !serviceRunning ){ // don't call for more data until
httpS.send(); // you've gotten back last call
}
}
private function resultHTTP(event:ResultEvent):void
{
// make sure we have differences before rebinding
var newData : String = event.result as String;
serviceRunning = false;
counter.text = Number(parseInt(counter.text,10)+1).toString();
if( newData != currentData ){
xmlData = event.result as XML;
currentData = newData;
xmlDataList = xmlData.dg.rows.row;
}
}
]]>
</mx:Script>
<mx:Label id="counter" text="0" horizontalCenter="0" verticalCenter="0" fontSize="72"/>
</mx:Application>
答案 1 :(得分:0)
如果我正确理解了您的代码,那么您正在从与SWF位于同一文件夹中的文件中恢复XML数据。如果是这种情况,那么最有可能发生的事情是XML文件正在浏览器中缓存,并且它会一遍又一遍地返回相同的缓存版本。
在处理这些问题时,您可以添加一个虚拟URL变量,使浏览器认为您要检索的文件是新的,并强制它再次恢复该文件。
您可以通过执行以下操作来实现此目的:
httpS.url = "data.xml?random="+Math.floor(Math.random()*1000);
如果这不能解决问题,那么可能与不重置保存实际XML数据的变量有关。您可以通过重置变量的新实例来完成此任务:
xmlData = new XML();
xmlDataList = new XMLList();
xmlC = new XMLListCollection();
或者,如果你想要的只是重置XMLListCollection,你可以尝试使用Flex中所有列表中包含的“refresh()”方法。
重要说明:如果您使用这些变量中的任何一个进行数据绑定,这可能会导致Flex无法对数据进行垃圾收集,因为它正在某处使用。
答案 2 :(得分:0)
请求,接收和处理XML需要多长时间?这听起来像是一个相当大的文件,所以如果它超过一秒钟,你将同时多次调用HTTPService(据我所知,你的当前计时器将尝试每秒发出一个请求,无论是否最后一个回来了。)
我不确定这是不是你想要的,但我对此表示怀疑。如果我是对的,并且你只想在得到最后一个请求之后发送请求,那么你可能最好摆脱计时器及其功能,然后将resultHTTP方法更改为类似这样:
private function resultHTTP(event:ResultEvent):void
{
xmlData = event.result as XML;
xmlC.source = xmlData.dg.rows.row;
httpS.send();
}
当然,您可能希望每次都开始延迟:
protected function application1_creationCompleteHandler(event:FlexEvent):void { httpS.url = "data.xml"; httpS.addEventListener(ResultEvent.RESULT, resultHTTP); httpS.resultFormat="e4x"; timer.start(); timer.addEventListener(TimerEvent.TIMER, updateXMLC); } private function updateXMLC(event:TimerEvent):void { timer.stop(); httpS.send(); } private function resultHTTP(event:ResultEvent):void { xmlData = event.result as XML; xmlC.source = xmlData.dg.rows.row; timer.start(); }
很抱歉,如果我误解了这个问题,那么......
无论哪种方式,你可能也希望将某种faultHTTP函数放入其中,因此它也会在HTTP错误上重新启动计时器(或做任何你需要做的事情)。
答案 3 :(得分:0)