2

画面回転時のビットマップとメモリ リークについて、インターネットで多くの投稿やコメントを読みました。

実際、私が経験している問題は非常に特殊です...

私は Eclipse DDMS を使用しており、4 つの ImageView に配置されたビットマップに関連する 1 バイト配列が占めるヒープ メモリを監視しています。それぞれが ViewFlipper のページに配置されています。画像は内部メモリから読み込まれ、サイズは 216 ~ 220KB です。レイヤ ドローアブルを使用して、その上に別の透明な画像を描画します。

ビットマップが占有するヒープ メモリに注目すると、デバイスの向きを変えると、メモリが数 MB 増加します。2 ~ 3 回の GC を引き起こし、しばらくするとメモリの量が初期値まで減少します。このプロセスをゆっくりと繰り返す (方向の変更 + 2 ~ 3 回の強制ガベージ コレクション) と、メモリの量は増加しますが、その後は同じ値に戻ります。これにより、アプリケーションでビットマップ管理を正しく行っていると思います。

しかし、デバイスを繰り返しすばやく回転させ始めると、メモリの量が継続的に増加することがわかります....そして、後続のGCは、高速回転中の急速な成長と比較して、ヒープ占有を少量のメモリでしか減らすことができません. .

Android はガベージ コレクションをそれほど高速に実行できませんか? しばらく GC を強制せずに高速回転を繰り返した場合ではなく、ゆっくり回転した場合にメモリ使用量を安定に保つことができるのはなぜですか?

アンドロイド 4.1.2 / サムスン ギャラクシー S3。

以下のコードは、png が内部ストレージから読み取られるか、インターネットから AsyncTask によってダウンロードされるたびに呼び出されます。AsyncTasks を無効にしても (したがって、後続のローテーションで保留中のタスクを除外します)、シーンは変わりません。起動時に内部ストレージから 2 つの「レイヤー」をロードして、デバイスのローテーション中にヒープをすばやく満たすだけで十分です。

public void setBitmap(Bitmap bitmap) 
{
    try{
        Drawable layers[] = new Drawable[2];
        Bitmap fvgBackgroundBmp = BitmapFactory.decodeResource(getResources(), R.drawable.fvg_background2);
        layers[0] = new BitmapDrawable(getResources(), fvgBackgroundBmp);
        layers[1] = new BitmapDrawable(getResources(), bitmap);
        LayerDrawable layerDrawable = new LayerDrawable(layers);
        setImageDrawable(layerDrawable);
        mLayerDrawableAvailable = true;
    }
    catch(Exception outOfMemory)
    {
        Log.e("setBitmap got exception", outOfMemory.getLocalizedMessage());
    }
}

からunbindDrawables()呼び出されたメソッドは役に立ちません:ActivityonDestroy()

public void unbindDrawables()
{
    if(mLayerDrawableAvailable)
    {
        LayerDrawable lDrawable = (LayerDrawable) getDrawable();
        if(lDrawable != null)
        {   
            lDrawable.getDrawable(1).setCallback(null);
            lDrawable.getDrawable(0).setCallback(null);
            lDrawable.setCallback(null);
        }
    }
}
4

2 に答える 2

0

onDestroy は、メモリ負荷が高い場合に呼び出される保証はありません。これはそれを説明するかもしれません。onStop() から unbindDrawables を呼び出してみてください

http://developer.android.com/training/basics/activity-lifecycle/stopping.html#Stop

于 2013-05-17T01:29:18.673 に答える