我已经在AS3中编程了一段时间,并发现一个非常奇怪的字符串问题,因为没有明显的原因挂在内存上,下面的程序只是用随机字符串更改label.text属性,它工作正常但当我看到Flex分析器时,我注意到Strings的数量正在稳步增加,我尝试执行垃圾收集器,但没有帮助我。
这是内存泄漏吗?我怎么解决呢?
我知道这些字符串应该由垃圾收集器收集,因为没有引用它们的对象,但是并没有发生所有字符串。
下面是代码和Flex分析器的屏幕截图,显示了String实例的数量。
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="windowedapplication1_creationCompleteHandler(event)">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected var t:Timer=new Timer(10);
protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
{
t.addEventListener(TimerEvent.TIMER,listener,false,0,true);
t.start();
}
protected function listener(e:Event):void
{
var s:String=Math.random()+"-->";
this.fx(s);
s=null;
}
protected function fx(s:String):void
{
this.label.text=s;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label id="label" y="39" left="10" right="10" text="Label"/>
</s:WindowedApplication>
对不起,不到10分,继承人的截图 http://imageshack.us/a/img11/9716/stackw.png
解决
Baris和Loxxy你是对的,我做了一些改变以便隔离问题并且它增长到~30Mb然后垃圾收集器释放一些内存,它永远不会回到~2mb(起始点)但是图表开始一遍又一遍地从~20mb到~30mb。
继承测试此代码的代码
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="windowedapplication1_creationCompleteHandler(event)">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected var maxMemoryUsage:Number=0;
protected var i:Number=0;
protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
{
setTimeout(Fx,20);
}
protected function Fx():void
{
if(i++%1024==0)
{
var mem:Number=System.totalMemory;
this.maxMemoryUsage = mem>this.maxMemoryUsage?mem:this.maxMemoryUsage;
trace(this.maxMemoryUsage + ' / ' + mem);
}
var s:String="";
s+=Math.random().toString()+"qwertyuiu...1024 random chars...iiwqe";
this.aSimpleString=s;
setTimeout(Fx,20);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:String id="aSimpleString"/>
</fx:Declarations>
</s:WindowedApplication>
同时调用System.gc()也没有做任何事情,也许gc需要暂停才能运行。
答案 0 :(得分:4)
垃圾收集器会在感觉到的时候运行。通常它会在分配新对象时发生,但如果内存使用率不高,则可能不会发生。
您可以尝试调用System.gc()
以查看它是否释放了这些字符串。但是你不应该在生产代码中使用它。
有关详细信息,请参阅this答案。
答案 1 :(得分:2)
您是否已经编写了一个低于建议延迟的计时器? new Timer(10);
来自here
建议不要超过20毫秒的延迟。定时器频率 限制为每秒60帧,意味着延迟低于16.6 毫秒会导致运行时问题。
正如Baris早先所说,人们在他们的应用程序中遇到大量内存,这是神奇的gc到达以解决内存问题的时候。除此之外,您既不需要担心它,也不能手动做任何事情。
答案 2 :(得分:0)
这可能与Master Strings有关,这是一个内存优化,Flash运行时用它来最小化相关字符串数据块的冗余分配。
您可以在此博文Flash String weirdness上阅读有关现实世界效果的详细分析。
以下是与SO相关的帖子的一些亮点:
结果
- 如果从长字符串中取一个部分字符串,它将保留长字符串。
- 如果您加入2个以上的字符串,它会将第二个字符串保留为主字符串。
- 如果你循环并将字符串添加到一起,它将与上面相同,它将从第三个开始保持一个主字符串 此外。
- 循环字符串测试似乎表明每个字符串都可以有一对父母。
- 这不符合,因为我们只能访问返回链的根的'getMasterString()'。
...
结论
- 字符串包含'父字符串'
- XML保留对其父字符串的引用
- 字符串可能会泄漏内存
- 由于上述原因,控制台图表似乎泄漏