5

私が持っている場合:

Bitmap bitmap = Bitmap.create(..); // instance a
bitmap = Bitmap.create(...); // instance b
bitmap = null;
bitmap = Bitmap.create(...); // instance c
bitmap.recycle();
bitmap = Bitmap.create(...); // instance d
bitmap.recycle();
bitmap = null;

このコードが実行されると、4つのインスタンスのうちどれがまだメモリに残っていますか?.recycle()がネイティブコードにすべてのリソースの割り当てを解除するように指示していることは知っていますが、それがいつ発生するかは保証されていません。

私が尋ねている理由は、次のループを見てみましょう:

Bitmap bitmap = null;

while (true) {
    bitmap = Bitmap.create(...);    
}

これは最終的にアプリをクラッシュさせる(メモリ不足)と思いますか?もしそうなら、このループはどのように書き直されるべきですか?(ビットマップを使用して、変更された状態をアニメーション化および表示している場合)。

4

2 に答える 2

1

Java(および拡張機能Android)は、非同期ガベージコレクションを使用して、割り当てられたメモリをクリーンアップします。コレクターはバックグラウンドで実行され、可能なメモリを解放します。これが意味することは、どの時点でも、到達不能なオブジェクトがクリーンアップされた数と、まだ保留中のオブジェクトの数を保証できないということです*。

最初のコードブロックの実行が終了した直後は、4つのBitmapオブジェクトすべてがまだヒープ上に存在している可能性がありますが、ある時点でガベージコレクターが実行され、それらがすべて到達不能であると判断され、関連するメモリが解放されます。

同じことが2番目のコードブロックにも当てはまります。任意の数のオブジェクトは、到達できなくなってもヒープ上に存在しますが、GCは、これが発生したときにそれらをクリーンアップするために最善を尽くします。実際には、GCはそのような短命のオブジェクトをクリーンアップするのに非常に優れているため、ループに追いつくことさえできる場合があります(ただし、これは保証ではありません)。

JVM / ARTはOutOfMemory、アプリケーションの実行を維持するために可能なメモリを再利用しようとする積極的なラストディッチガベージコレクションなど、状況を回避するために最善を尽くします。したがって、2番目のループで問題が発生する可能性は低いですが、テストするのは簡単です。

うまくいけば、文字通り何千ものBitmapオブジェクトを作成してすぐに破棄するのではありません。おそらく、それらは少なくとも一定期間使用されており、その間Bitmap、文字通り使用されないものをさらに作成しているだけではありません(そうであれば、それが問題です)。

*ガベージコレクションのステータスを監視できる、を使用するなどのトリックがありますがPhantomReference、これらはGCに大きな負担をかけるため、一般的にはお勧めできません(または必要ではありません)。

于 2016-07-23T23:26:42.977 に答える
0

Androidは、Javaとほぼ同様に機能するDalvikVMを使用します。必要な場合を除いて、再収集は行いません。

MATは、Android用のhprofを使用してメモリダンプを分析するための優れたツールです。

MATを使用して自分で答えを見つけることができます

于 2012-08-18T15:49:03.860 に答える