2017-11-07 15 views
2

私はFlashエディターから画像をレンダリングするAIRアプリケーションを持っています。複数のサーフェスをカスタマイズすることができます。サーフェスはすべて同じ幅と高さを持ちます。その後、各サーフェスはAIRアプリケーションによってレンダリングされます。ビットマップデータメモリリークのAS3描画Sprite

メモリリークに苦労しています。私は対処できません。

レンダリングが必要な各サーフェスには、多くのコンポーネント(他のスプライト - イベントリスナー、ビットマップデータ、その他の子コンポーネント、スプライトなどを含むスプライト)があります。私はすでにゴミを収集するのBitmapData問題を認識してい

は、私は両方をテストした:

それぞれ(処分後、レンダリングのための新しいのBitmapDataを作成
  • )とポイントの単一のBitmapDataを再利用
  • をゼロにするために各レンダリング

メモリリークはまだ等しく発生しています。

var bm:BitmapData = new BitmapData(destDim.x, destDim.y, true, bgColor); 
var mtx:Matrix = new Matrix(); 
trace('before drawing :'+(System.privateMemory/1024)); 
bm.draw(myBigSprite, mtx, null, null, null, true); 
trace('after drawing :'+(System.privateMemory/1024)); 
var result:Bitmap = new Bitmap(bm, PixelSnapping.NEVER, true); 

//return result and encode Bitmap to png 

result.bitmapData.dispose(); 
result.bitmapData = null; 
result = null; 

結果::私は描画機能の動作中に何かが欠けているように私は感じ

before drawing :208364 
after drawing :302816 
Wrote bitmap to file: surface0.png 
before drawing :303296 
after drawing :446160 
Wrote bitmap to file: surface1.png 
before drawing :446160 
after drawing :565212 
Wrote bitmap to file: surface2.png 
before drawing :565924 
after drawing :703100 
Wrote bitmap to file: surface3.png 
before drawing :703572 
after drawing :834420 
Wrote bitmap to file: surface4.png 

は、ここに私のループです。私は、描画操作後も持続するmyBigSpriteのコンポーネントのインスタンスを新しく作成したようです。

私は、任意のヒントをいただければ幸いです

....それは何も変更しない、完全に各ループの最後でmyBigSpriteを破壊しようとしました!

+0

あなたはどのようにガベージコレクションプロセスが実行されましたか?あなたはそれを強制するのですか?またサイドノートとして、System.gc()を呼び出すことによってgcを強制することは、私が知る限りデバッグプレーヤーでのみ動作します。 – Patang

+0

描画操作の終わりから次の操作の開始までのメモリはほぼ同じですが、その間に多くのメモリを消費する操作があります。特にビットマップをpngにエンコードする。だから私はGCのプロセスは、私が掃除したいすべてのリソースが描画機能を除いて清掃されているので、その仕事をしていると仮定します。私はSystem.gc()を明示的に呼び出すことはありません。 – Bedu33

+0

ビットマップデータへの参照を保持しているので、 "result"をnullに設定していますか? – Patang

答えて

0

皆、私は最終的にこの問題を理解して修正しました。

まず、私はAdobe Scoutをインストールして実行しました。優れたツール。

Adobe Scout memory profiling

あなたが表示されない場合があります(プラスそれはフランス語で)のような、私はエッジに対応する3面を生成しました。右側にある大容量のメモリである「大きな」緑色のバーは、「ビットマップ表示オブジェクト」を表します。面白い !以前は聞いたことがありません。

Google検索は、後に、私はこの記事を見つけた:https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e26.html

ピクトLoaderオブジェクトのロード 操作が完了したら、それは、先に示したコードの抜粋では、例えば

を説明しますpictオブジェクトは ビットマップである1つの子表示オブジェクトを持っています。 このビットマップ表示オブジェクトにアクセスするには、pict.getChildAt(0)を記述します。

私は、どういうわけか、ビットマップオブジェクトが、のオブジェクトの一部として子として添付されている可能性があることに気付き始めました。

は最後に、私は

private function destroyDisplayObjects(obj):void{ 
    if ("numChildren" in obj){ 
     for (var i:int = 0; i<obj.numChildren; i++) 
     { 
      destroyDisplayObjects(obj.getChildAt(i)); 
     } 
    } 
    else { 
     if (flash.utils.getQualifiedClassName(obj) == "flash.display::Bitmap"){ 
      //trace ('FREE BITMAP'); 
      obj.bitmapData.dispose(); 
      obj.bitmapData = null; 
      obj = null; 
      return; 
     } 
     else if (flash.utils.getQualifiedClassName(obj) == "flash.display::BitmapData"){ 
      //trace ('FREE BITMAPDATA'); 
      obj.dispose(); 
      obj = null; 
      return; 
     } 
     else if (flash.utils.getQualifiedClassName(obj) == "flash.display::ByteArray"){ 
      //trace ('FREE BYTEARRAY'); 
      obj.clear(); 
      obj = null; 
      return; 
     } 

     return; 
    } 
} 

ほら、メモリ...

draw操作後 myBigSpriteに含まれるすべての BitmapBitmapDataByteArrayオブジェクトを検索し、破壊するために
//inside render function 
bm.draw(myBigSprite, mtx, null, null, null, true); 
destroyDisplayObjects(myBigSprite); 

を再帰関数を作成しましたドロー操作後に100%清掃され、それ以上のリークはありません:)

0

BitmapBitmapDataを関数の外に宣言して、ループ内で使用するためにリサイクルしてください(メモリ内に何かを追加する代わりにnewを作成するのではなく)。

bmの変数のビットマップデータがもう必要ないと確信したときは、最後の画像にのみ.dispose()を使用してください。それ以外の場合は、処分された場合は、もう一度使用するために新しい代替品var someThing :BitmapData = new BitmapDataをもう一度作成する必要があります。

////# declare globally (not inside some specific function..) 

//var destDim :Point = new Point(your_X_num , your_Y_num); 
//var bgColor :uint = 0x505050; 

var bm:BitmapData = new BitmapData(destDim.x, destDim.y, true, bgColor); 
var result:Bitmap = new Bitmap(bm, PixelSnapping.NEVER, true); 
//result.bitmapData = bm; //can be set here but done within function for clarity... 

var mtx:Matrix = new Matrix(); 


////# update bitmap by replacing its bitmapdata with new colour values of existing pixels 

function Here_is_my_loop(): void 
{ 
    trace('before drawing :'+(System.privateMemory/1024)); 

    //overwrite pixel colours in bitmap (result) 
    bm.draw(myBigSprite, mtx, null, null, null, true); 
    result.bitmapData = bm; //update bitmap 

    trace('after drawing :'+(System.privateMemory/1024)); 


    //return result and encode Bitmap to png 

    //result.bitmapData.dispose(); 
    //result.bitmapData = null; 
    //result = null; 
} 
+0

あなたの答えをありがとう。残念ながら、元の投稿で述べたように、私は再利用されたBitmapDataで全く同じ結果を得ています。 しかし、もう一度あなたの解決策を試しましたが、同じ結果があることを確認します。 – Bedu33

+0

うーん、私が見逃していたかどうかわからない_ "各レンダリングのために単一のBitmapDataを再利用する" _最後に、ループで 'new'を使うのはメモリを食べる良い方法です。私のコードは**既存のデータを上書きするだけで済みますので、何らかの** **新しいデータを追加する(メモリ使用量を増やす)ことを理解できません。可能であれば、Flashに飛び乗るために調査します。 –

+0

"私のコードは既存のデータを上書きして、何らかの形で新しいデータを追加する(メモリ使用量を増やす)のを理解できない" これはまさに私の質問です:) – Bedu33

関連する問題