3

そのため、大きなビットマップが原因で悪名高い oom エラーが発生しています。しかし、私はほとんどの問題を解決することができました。残っている唯一の問題は、[戻る] をクリックしてアプリを閉じ、その直後にアプリを起動したときに発生します。その後、アプリがクラッシュし、oom (メモリ不足) エラーが発生します。ホームをクリックしても、これは起こりません。

なぜこうなった?私の推測では、GC のクリアが完了していないため、古いデータがまだ残っている間に GC を開始します。もちろん、これは新しいアプリではないため、古い起動と新しい起動は同じアプリのメモリ制限の下に置かれます。

この問題に関する情報と考えられる解決策は素晴らしいものです。

私が試したこと:

私が使用したビットマップのすべてのダウンロードで:

BitmapFactory.Options op = new Options();
op.inPurgeable = true;
bmImg = BitmapFactory.decodeStream(is,null,op);

画像の幅 x 高さを小さくします (KB 単位のサイズはほぼ同じです)。<-- これで問題が解決するので、優れたソリューションを持っている人がいない限り、フォールバック ソリューションがあります :)

エラーログの抜粋:

06-25 04:29:28.917: E/AndroidRuntime(8819): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.content.res.Resources.loadDrawable(Resources.java:1713)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.widget.ImageView.<init>(ImageView.java:122)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.widget.ImageView.<init>(ImageView.java:112)
06-25 04:29:28.917: E/AndroidRuntime(8819):     ... 23 more

編集:2つのことが私にとってこの問題を解決します。

  1. データベースをクリアし、メイン アクティビティの ondestroy() で大きな画像を null に設定します。
  2. 大きな画像を小さくします。

しかし、これは同じ基本的な問題を引き起こします。 onDestroy() が呼び出された場合、新しいアクティビティが開かれる前にアクティビティが適切に閉じられないのはなぜですか? また、アクティビティが閉じられた後もずっと実行されていることがわかります。これは問題に関連している可能性がありますか? この原因を突き止めるにはどうすればよいですか?

Edit2 :犯人は私のLruCacheのようです。ondestroy() でクリアされない静的 lrucache を使用します。アプリを再起動すると、lrucache 内のすべての画像がまだ存在し、問題が発生します。なぜこれが再起動時にのみ問題になるのか、まだ疑問に思っていますか? これも、閉じる直前に本業に戻ったときに問題になるのではないでしょうか?

4

3 に答える 3

2

プロセスを強制的に閉じることで解決された同じ問題がありました。これは、onDestroy() をオーバーライドすることで実行できます。これを使って:

@Override
public void onDestroy(){
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses();
    for (int i = 0; i < pids.size(); i++) {
        ActivityManager.RunningAppProcessInfo info = pids.get(i);
        if (info.processName.equalsIgnoreCase(context.getPackageName())) {
            android.os.Process.killProcess(info.pid);
        }
    }
    super.onDestroy();
}
于 2012-06-18T14:09:57.400 に答える
1

ねえ、同じ問題に関する私の答えを確認してください:ビットマップ サイズが Vm 予算エラー android を超えています

また、次のようなビットマップを扱うときは、常に最大のオプションを使用するようにしてください。

        final Options options = new Options();
        options.outHeight = (int) scaleHeight; // new smaller height
        options.outWidth = (int) scaleWidth;   // new smaller width
        options.inScaled = true;
        options.inPurgeable = true;

        // to scale the image to 1/8
        options.inSampleSize = 8;
        bitmap = BitmapFactory.decodeFile(imagePath, options);

これで問題が解決する場合があります。

于 2012-06-18T12:38:42.187 に答える
0

原因は私の LruCache にあるようです。ondestroy() でクリアされない静的 lrucache を使用します。アプリを再起動すると、lrucache 内のすべての画像がまだ存在し、問題が発生します。なぜこれが再起動時にのみ問題になるのか、まだ疑問に思っていますか? これも、閉じる直前に本業に戻ったときに問題になるのではないでしょうか?

それにもかかわらず、この問題の一時的/永続的な修正は、ondestroy() 内のすべての静的参照を消去することですが、小さいサイズの画像も使用することです。メモリリークも見つからないため、これですべての問題が解決したようです。

于 2012-06-20T10:05:09.687 に答える