web-dev-qa-db-ja.com

(Androidで)使用した後にBitmap.recycle()を呼び出す必要がありますか?

Android Bitmap.recycle()のリファレンスドキュメントによると:

このビットマップに関連付けられているネイティブオブジェクトを解放し、ピクセルデータへの参照をクリアします。これは、ピクセルデータを同期的に解放しません。他に参照がない場合は、ガベージコレクションを許可するだけです。ビットマップは「デッド」としてマークされます。つまり、getPixels()またはsetPixels()が呼び出されると例外がスローされ、何も描画されません。この操作を元に戻すことはできないため、ビットマップをこれ以上使用しないことが確実な場合にのみ呼び出す必要があります。 これは高度な呼び出しであり、このビットマップへの参照がなくなると通常のGCプロセスがこのメモリを解放するため、通常は呼び出す必要はありません。

しかし、私が読んだ多くの本は、Bitmap.recycle()を呼び出してメモリを解放することを提案しています。

それは私を混乱させます:使用後にBitmap.recycle()を呼び出す必要がありますか?

17
Marton_hun

場合によります。

Android 3.0以降でアプリを実行する場合、GCが完全に処理するため、アプリは必要ありません。

ただし、古いバージョンでアプリを実行すると、ビットマップはGCによって適切に監視されないため(参照のサイズであると見なされます)、Google IO講義 ここ

いずれにせよ、ビットマップが不要になったことを確認したらすぐにrecycleを呼び出すことをお勧めします。自動メモリ管理に必要な作業が軽減されるため、新しいAndroidバージョンでも問題ありません...

実際、私は同様の質問をしたことを覚えています ここ

また、JNIを使​​用してビットマップをさらに制御する必要がある場合は、 この投稿 を確認してください。

つまり、答えは、もはや必要ではないが、それでも推奨されるということです。


編集:Android 8.0以降、ビットマップはネイティブメモリに保存されるため、OOMに到達するのは困難です。実際、代わりに他の問題が発生するため、技術的に不可能です。これに関する詳細情報見つけることができます ここ

18

必須ではありませんが、強くお勧めします。これにより、メモリ解放プロセスが高速化され、メモリ不足の例外を除いて拷問から解放されます。

あなたがビットマップで深刻なメモリの大規模な作業を行うつもりなら、それは必須だと思います。

1
JanBo

以前のAndroid 3.0ビットマップはネイティブメモリを割り当ててそのピクセルを保存し、recycle()はその領域でdeleteを呼び出します。

それでも、GCは、参照がまだある場合、そのメモリを解放することは保証されていません。

しかし、この呼び出しはGCの動作を改善するのに役立つようです。メモリを大量に使用し、新しいデバイスで実行するアプリを開発しました。アプリがほぼ同じように実行されるかどうかは関係ありません(古い場合はパフォーマンスが大幅に向上します)。

0

私の経験では、本番コードで大量のビットマップ圧縮を実行し、recycle()を呼び出さずに、古いLollypopデバイスで多くのOOM例外に遭遇し、それをコードに追加した後、 OOMのが大幅に減少しました。

0
yshahak