2

これは、BitmapDataメモリ割り当てのためのAS3での簡単なテストです。

private function memoryTest(): void
{
  trace("BitmapData memory test. Create bmps..."); // First breakpoint
  var bmps:Array = new Array (1000);

  for (var i:int=0; i<1000; i++)
  {
    bmps[i] = new BitmapData(451, 451, true, 0);
    trace(i+". bmp created");
  }

  trace("All bmps created."); // Second breakpoint

  for (i=0; i<1000; i++)
  {
    bmps[i].dispose();
    bmps[i] = null;
  }
  bmps.splice(0, bmps.length);
  bmps = null;

  freeMemoryGC();

  trace("All bmps deleted.");
  trace("Test complete."); // Last breakpoint
}

private function freeMemoryGC(): void
{
  // the GC will perform a full mark/sweep on the second call.
  try
  {
    new LocalConnection().connect('foo');
    new LocalConnection().connect('foo');
  }
  catch (e:*)
  {
  }

  System.gc();
  System.gc();
}

このテストには3つのブレークポイントがあり、コードでコメント化されています。ブレークポイントは、しばらくの間プログラムを一時停止します。ブレークポイントは、このメモリ状態チャートの水平線に対応しています。

メモリ使用量グラフ

私の質問は、dispose()の呼び出し後にすべてのメモリが解放されなかったのはなぜですか?このコードの何が問題で、BitmapDataオブジェクトを適切にクリアする方法は?

更新1:ガベージコレクターに問題があるとは思わない。dispose()はGCで機能し、ピクセルデータを解放する必要があります。また、この例では、理論的には451 * 451 * 4*1000バイトを割り当てる必要があります。ただし、このテストアプリケーションはSystem.privateMemoryに25%多いバイトを割り当て、これらの25%はGCおよびdispose()によって解放されることはありません。

更新2:100枚の画像451x451ピクセルではなく13枚の画像4059x4059ピクセルを作成すると、メモリは理論上のサイズとまったく同じに割り当てられ、メモリはGCの呼び出し後に適切に解放されます。なぜそれが起こるのか分かりません。

UPDATE3:ダニエル・メッサーが彼の答えで作成したインターバルテストの結果は次のとおりです。 区間テストのメモリ使用量グラフ

4

1 に答える 1

0

空きmemorygc-functionのローカル接続に関することを削除してみてください。それはそれを解決しますか?

編集:

package nyx_gaming_group.as3_tests {
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.system.System;
import messer_entertainment.MesSerUtils;

/**
 * ...
 * @author Daniel Dahlkvist
 */
public class BitmapDataMemoryLeak extends Sprite {
    private var _bitmaps:Array;

    public function BitmapDataMemoryLeak() {
        run();
    }

    private function run():void {
        MesSerUtils.delayCall(createBitmaps, 150);
        MesSerUtils.delayCall(destroyBitmaps, 4500);
        MesSerUtils.delayCall(freeMemoryGC, 4700);
        MesSerUtils.delayCall(run, 8000);
    }

    private function createBitmaps():void {
        trace("BitmapData memory test. Create bmps..."); // First breakpoint
        _bitmaps = new Array(1000);

        for (var i:int = 0; i < 1000; i++) {
            _bitmaps[i] = new BitmapData(451, 451, true, 0);
        }

        trace("All bmps created."); // Second breakpoint            
    }

    private function destroyBitmaps():void {
        for (var i:int = 0; i < _bitmaps.length; i++) {
            _bitmaps[i].dispose();
            _bitmaps[i] = null;
        }
        _bitmaps = null;

        trace("All bmps deleted.");
        trace("Test complete."); // Last breakpoint
    }

    private function freeMemoryGC():void {
        System.gc();
    }
}
}
于 2012-08-06T17:37:48.107 に答える