AS3字符串内存泄漏



我在AS3中编程已经有一段时间了,发现字符串有一个非常奇怪的问题,因为没有明显的原因,它挂在内存上,下面的程序只是用一个随机字符串更改了label.text属性,它工作得很好,但当我查看Flex探查器时,我注意到字符串的数量正在稳步增加,我试着执行垃圾收集器,但没有帮到我。

这是内存泄漏吗?我该怎么解决?

正如我所知,这些字符串应该由垃圾收集器收集,因为没有对象引用它们,但并不是所有字符串都会发生这种情况。

以下是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分,这是profilers的截图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需要一些暂停才能运行。

垃圾收集器将随时运行。通常在分配新对象时会发生这种情况,但如果内存使用率不高,则可能不会发生这种情况。

您可以尝试调用System.gc(),看看它是否释放了这些字符串。但您不应该在生产代码中使用它。

有关详细信息,请参阅此答案。

你没有写一个定时器来运行低于建议的延迟吗?new Timer(10);

从这里

不建议延迟低于20毫秒。定时器频率被限制为每秒60帧,这意味着延迟低于16.6毫秒会导致运行时问题。

正如Baris早些时候所说,人们在应用程序中会遇到大量内存,这就是神奇的gc来解决内存问题的时候。除此之外,你既不需要担心它,也不能手动对此做任何事情

这可能与主字符串有关,主字符串是Flash运行时用来最小化相关字符串数据块冗余分配的内存优化。

你可以在这篇博客文章中阅读关于现实世界影响的详细分析。

以下是该帖子中与SO相关的一些亮点:

结果

  • 如果从长字符串中提取部分字符串,它将保留该长字符串
  • 如果连接两个以上的字符串,它将保留第二个字符串作为主字符串
  • 如果你循环并将字符串添加到一起,它将与上面一样,从第三个开始保留主字符串此外
  • 循环字符串测试似乎表明每个字符串都可能有一个父字符串链
  • 这是不符合的,因为我们只能访问返回链根的"getMasterString()">

结论

  • 字符串具有"父字符串">
  • XML保留对其父字符串的引用
  • 字符串可能会泄漏内存
  • 由于上述原因,控制台图形出现泄漏

最新更新