2012-01-05 13 views
1

私のアプリは何らかの理由で、実行中にますます多くのメモリを使用しています。古いデータをダンプする方法がわかりません。AS3 - 空きメモリ(Loader、BitmapData)?

ローダーを使用して.pngをロードします。 次に、BitmapDataを使用して画像を保存します。その結果、各ピクセルをチェックして結果を保存できます。

これをx回ループします。

私は2番目の実行で起動したときに、私はもう古い情報は必要ありませんが、私のアプリはまだ(イメージがロードされた)データを格納しているように見える。..

ここに私のコードの一部です:

 public function loadImage():void{ 
      myLoader = new Loader(); 
      myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded); 

      if (currentFrame.toString(10).length == 1){ 
       currentFrameURL = txtFolder.text + "\\" + txtImageName.text + txtImageNum.text.substr(0, txtImageNum.text.length - 1) + currentFrame + txtImageType.text; 
      } 
      if (currentFrame.toString(10).length == 2){ 
       currentFrameURL = txtFolder.text + "\\" + txtImageName.text + txtImageNum.text.substr(0, txtImageNum.text.length - 2) + currentFrame + txtImageType.text; 
      } 
      if (currentFrame.toString(10).length == 3){ 
       currentFrameURL = txtFolder.text + "\\" + txtImageName.text + txtImageNum.text.substr(0, txtImageNum.text.length - 3) + currentFrame + txtImageType.text; 
      } 
      trace(currentFrameURL + " sent to loader..."); 

      myLoader.load(new URLRequest(currentFrameURL)); 
     } 

     public function imageLoaded(event:Event):void{ 
      myLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, imageLoaded); 

      myBitmapData = new BitmapData(parseInt(txtWidth.text),parseInt(txtHeight.text),false); 
      myBitmapData.draw(event.currentTarget.content); 


      //Generate preview of current image being processed.. 
      //myPreviewImage.source = myBitmapData; 
      labelProgress.text = "Current process: " + (currentFrame + 1) + "/" + (parseInt(txtFrames.text)); 


      for(var y:int=0; y < parseInt(txtHeight.text) ; y++){ 
       for(var x:int=0; x < parseInt(txtWidth.text) ; x++){ 
        currentPixelColor = myBitmapData.getPixel(x,y); 
        myTabelClass.recordPixel(currentPixelColor); 
       } 
      }//ett bilde ferdig scannet og lagret 

      currentFrame++; 

      if(currentFrame < parseInt(txtFrames.text)){ 
       myTabelClass.newImg(currentFrame); 
       trace("sending newImg command: " + currentFrame); 
       loadImage(); 
      }else{ 
       //All frames done.. 
       //myTabelClass.traceResult(); 
       Alert.show("All images scanned!\n\nClick 'OK' to add new data to XML.", "Images scanned", Alert.OK, this, insertDataToXML); 
       btnSave.enabled = true; 
       btnTest1.enabled = true; 
      } 

     } 

答えて

1

残念ながら、Loaderがメモリを解放するのを防ぐバグがあります。https://bugbase.adobe.com/index.cfm?event=bug&id=3071138を参照してください。私のテストでは、以前にロードされたコンテンツをどのくらい速く処理したいのかが関係しているかもしれませんが、これはと思われます。

その他のもの:BitmapData.dispose()を呼び出すとメモリが即座に解放されますが、そうでない場合はBitmapDataインスタンスがGCで処理されますが、時間がかかることがあり、ビットマップが壊れてメモリリークが発生することがあります。

System.gc()は、デバッガでのみ使用できます。つまり、エンドユーザーはデバッガを使用できません。

オブジェクトを使用しなくなった後の変数、特にローカル変数をnullに設定することは意味がありません。コンパイラが少しスマートになっていれば、それをデッドコードとみなして完全に削除するでしょう。データメンバをnullに設定するのは、 "ビジネスロジックの理由"と呼ばれ、GCを "支援"しようとしないと、実際に何らかの理由でnullにしたい場合にのみ便利です。より良い害をしてください。 nullというコードを見つけると、通常は赤い電球が点灯しますが、デザインや冗長性は悪いです。あなたのコードが良ければ、それをする必要はありません。

+0

あなたの有用な入力をありがとう! =) 小さい画像(少ないデータ)を使用するとアプリケーションGCが正しく表示されますが、フルフレームの例のフレーム97に達したので一晩の実験に失敗しました。私はそれについてもっと見ていきます。 –

+0

これをマルチスレッドにする方法はありますか? 私は2つのXeonプロセッサを持っています。これは私に16のスレッドを与えます。私のアプリは100%で1スレッドしか使用していません..それは重要ではありませんが、それが可能だった場合は、私のアプリを16倍にスピードアップします。 –

+0

あなたはそれを処分する時間を与えていますか? GCコールには時間がかかりますが、即時ではありません。プロファイラを使用します。 Loader/BitmapDataは私のために大丈夫です。 – ansiart

0

あなたは再帰しているので、読み込まれたプレビュー画像を解放しません。

myBitmapData = nullにもう一度お電話の前にloadImage()に電話してください。

何も起こらない場合は、loadImage前System.gc()を呼び出すことにより、ガベージコレクタを強制しようとすることができます

myBitmapData = null; 
System.gc(); 
loadImage(); 

をしかし、彼らが言う良い練習がないthatsの。 :P

何も役に立たないのであれば、役立つかもしれない再帰的なものを削除するだけです。

+0

ありがとうございます。私は今それを試してみるでしょう。 再帰を削除するとどういう意味ですか? –

+0

'loadImage'は' imageLoaded'を呼び出し、 'imageLoaded'は' loadImage'をもう一度呼び出します。この再帰を使わずにロジックをリメイクする必要があるかもしれません。 – Fabricio

+0

ああ、私はそれを見ていきます:)それを指摘してくれてありがとう;) しかし、100%再帰なしでこれをやっているとは思いません。 –

3

myBitmapDataが完了したら、myBitmapData.dispose()myBitmapData = nullと電話してください。 dispose()に電話した後、BitmapDataオブジェクトはもはや使用できないため、新しいインスタンス(myBitmapData = new BitmapData())を作成する必要があります。

ところで、コードはあまり分析しませんでしたが、各画像のビットマップデータをdraw()でコピーしてから作業したことに気付きました。

myBitmapData = Bitmap(event.target.content).bitmapData;

を、あなたが後でそれらを使用する予定がない場合は、次のフレームに進む前にnullに各画像を忘れないでください:あなたは、同様に、メモリを節約するであろうと、読み込んだ画像のコンテンツを直接操作することができます。

+0

私はmyBitmapData.dispose()を追加しようとしました。最終的には、次回画像をロードするときにエラーが発生します。 –

0

その他の回答ではBitmapDataの処理方法が説明されていますが、Loaderもメモリに保持されているようです。残念ながら私は私の経験以外の特定の情報源を指摘することはできません。あなたはアウト揺れるかを確認するには、この試してみることができます。loadImage()機能のうち

移動ライン

myLoader = new Loader(); 

をし、クラスのコンストラクタでその変数をインスタンス化します。これにより、同じLoaderインスタンスを繰り返し再利用することができます。

+0

ありがとうございました。私はこれを試してみましょう:) –

関連する問題