2012-10-10 62 views
3

我一直在AS3編程一段時間,發現一個非常奇怪的問題,因爲沒有明顯的理由掛在內存中,下面的程序只是改變label.text屬性隨機字符串,它工作正常,但當我看着Flex Profiler我注意到字符串的數量穩步增加,我試圖執行垃圾收集器,但沒有幫助我。AS3字符串內存泄漏

這是內存泄漏嗎?我該如何解決它?

據我所知,這個字符串應該被垃圾收集器收集,因爲沒有對象引用它們,但這並不是所有的字符串都會發生。

下面是代碼和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

解決

巴里斯和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希望以運行一些暫停。

+1

如果在緊密的循環中非常快速地生成字符串,可能是垃圾收集器沒有足夠的時間來釋放字符串。我只是在這裏猜測,自從我做AS3工作已經有一段時間了。 10ms似乎並不是那麼快,但我在AS3中看到了一些陌生的東西。你嘗試過一個更慢的計時器嗎? – xxbbcc

+0

是的,實際上這是一個測試im與其他程序沒有使用計時器相同的問題,也嘗試通過Flex profiler接口強制垃圾收集器 – DooMMcQ

+0

或者你可以嘗試安裝不同的播放器版本 - 我見過Adobe介紹當他們發佈一個新版本時,他們經常會遇到主要的Flash Player錯誤。您的當前版本有可能存在GC錯誤。你的代碼看起來正確。 – xxbbcc

回答

4

無論何時感覺,垃圾收集器都會運行。通常它發生在新對象的分配上,但如果內存使用率不高,它可能不會發生在您的情況中。

您可以嘗試致電System.gc()以查看是否釋放了這些字符串。但是你不應該在你的生產代碼中使用它。

請參閱this回答獲取更多信息。

+1

但是,您不應該在生產代碼中使用該版本。 =>其實你不能,它只能在調試閃存播放器上使用。 – blue112

+0

添加了一個按鈕來調用System.gc(),但仍然是相同的行爲,即時讓程序運行以便使用更多內存,字符串實例現在使用6mb的80%,這是我的程序正在分配的總內存 – DooMMcQ

+0

是啊6MB沒什麼,就像我說的那樣,當GC感覺像GC時就會釋放東西。你的代碼沒有錯,實際上你甚至不需要將字符串作爲空值,因爲它是一個局部變量,並且在函數結束時超出範圍。 –

2

您是否寫過計時器以在推薦的延遲以下運行? new Timer(10);

here

的延遲低於20毫秒,不推薦。定時器頻率 限制爲每秒60幀,這意味着延遲時間低於16.60毫秒會導致運行時問題。

正如Baris早些時候所說的,人們在其應用程序中遇到大量內存,這就是當神奇的gc到達解決內存問題的時候。除此之外,你不需要擔心它,也不能手動做任何事情。

+0

將計時器更改爲500毫秒,通過連接更多隨機數來增加字符串的大小以增加內存使用量,但沒有區別:( – DooMMcQ

0

這可能與Master Strings,使Flash運行時使用,以儘量減少串數據的相關區塊的冗餘分配的內存優化。

你可以閱讀關於這個博客帖子Flash String weirdness現實世界的影響進行詳細分析。

下面是帖子的一些亮點是相關的SO:

結果

  • 如果你從一個長的字符串部分字符串,它會保持很長的字符串。
  • 如果您加入2個以上的字符串,它會將第二個字符串保留爲主字符串。
  • 如果您循環並添加字符串,它將與上面相同,它將從第三個 加法開始保留主字符串。
  • 循環字符串測試似乎表明每個字符串都可能有父母鏈。
  • 這不能符合,因爲我們只能訪問'getMasterString()',它返回鏈的根。

...

結論

  • 字符串有 '父字符串'
  • XML保持引用到它的父字符串(S)
  • 字符串會出現內存泄漏
  • 控制檯由於以上原因,圖表似乎泄漏