アプリケーションに多くのビットマップがあります。アプリケーションの起動時にロードされます。1 つのアクティビティでは、言語を変更する 2 つのボタンがありますが、ボタンをクリックすると、画像の読み込みが再開されます。時々、メモリ不足でエラーが発生します。ボタンをクリックするとメモリがクリーンアップされ、その後ビットマップがロードされるというメモリをクリーンアップするにはどうすればよいですか? これは可能ですか?今は使用していますsystem.exit(0)
が、すべてのアプリケーションを閉じたくありません。
3 に答える
少し前にグラフィック処理の集中的なアプリで同じ問題に直面していましたが、多くのデバッグを行った後、Bitmap オブジェクトが自動的に適切に解放されないことがわかりました。
ビットマップが不要になったらすぐにリサイクル メソッドを呼び出して、自分でビットマップを管理する必要があります (Activity.onStop メソッドなど)。
編集 (2014 年 10 月 8 日):
Android 開発者向けドキュメントに、これらのビットマップ メモリの問題に関する明確な説明がついに含まれています。その間、いくつかのことが改善されましたが、ビットマップ メモリ管理を困難にする古いバージョンの Android に対処する必要があります。
重要なポイントは次のとおりです。
Android 2.3.3 (API レベル 10) 以下
- ピクセルデータはネイティブメモリに保存されます...
- ... Dalvik ヒープ メモリにはありません
- ピクセル データが予期しない方法でリリースされる
この問題は、ビットマップ (または他の大きなオブジェクト) で Dalvik ヒープ メモリの制限を既に使い果たし、別のビットマップを読み込もうとした場合に発生します。古いビットマップ オブジェクトの参照をもう保持していない場合でも、新しいビットマップ オブジェクトが割り当てられる前にそれらのビットマップがガベージ コレクションされることは保証されません。したがって、ランダムに制限に達してOutOfMemoryError
.
したがって、ビットマップ オブジェクトを自分で管理することが重要です。ビットマップの使用が終了したら、recycle()
別のビットマップをロードする前にそのメソッドを呼び出す必要があります。
Android 3.0 (API レベル 11) 以降
- ピクセル データは、ビットマップ オブジェクトと共にDalvik ヒープに格納されます。
ここで、Dalvik のメモリ マネージャーは、メモリの残量を確認し、メモリの再利用を完全に制御できます。
ビットマップの管理
どちらの場合も (古いバージョンの Android と新しいバージョン) 、次のことを避けるためにビットマップ オブジェクトを管理する必要がある場合があります。
- 同じ画像の繰り返し読み込み (最適化の問題)
- メモリ不足 (安定性の問題)
Android 開発者向けドキュメントには、最長未使用キャッシュ (LruCache)を使用して、既に読み込まれているビットマップ オブジェクトをキャッシュして再利用する方法に関する詳細情報が含まれています。
未使用のビットマップがデータ構造から参照されず、recycle
適切に呼び出された場合、OutOfMemory 例外は発生しません。これを確認するとすぐに、自動化されたガベージ コレクターが確実にサービスを開始し、いつデータを解放するかを伝える必要がなくなります。
プログラム内の静的変数、特にコレクションや複雑な構造に注意してください。ビットマップがどこかに追加された場合は、そこから再度削除されていることを確認してください。
System.exit(0)
JVM が終了するため、呼び出さないでください。bitmap.recycle()
使い終わったら、すべてのビットマップを呼び出します。これにより、ビットマップによって取得されたネイティブ メモリが解放されます。また、ビットマップ参照を null に設定すると、GC は次回の実行時にそれを収集します。
この答えはあなたを助けるでしょう:ビットマップのデコードで OutOfMemoryError をキャッチする