AS3字符串内存泄漏

时间:2012-10-10 14:16:31

标签: actionscript-3 flex memory-management memory-leaks flex4.5

我已经在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需要暂停才能运行。

3 个答案:

答案 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保留对其父字符串的引用
  •   
  • 字符串可能会泄漏内存
  •   
  • 由于上述原因,控制台图表似乎泄漏
  •