あなたのジレンマに対処するために、これは予想される動作だと思います。
メモリを解放したい場合は、ときどき を呼び出すことができますがSystem.gc()
、実際にはほとんどの場合、ガベージ コレクション自体を管理させる必要があります。
私がお勧めするのは、各ビットマップが占有しているバイト数を計算することにより、独自のメモリ使用量を追跡する何らかの種類の単純なキャッシュ (URL/ファイル名からビットマップへ) を保持することです。
/**
* Estimates size of Bitmap in bytes depending on dimensions and Bitmap.Config
* @param width
* @param height
* @param config
* @return
*/
public static long estimateBitmapBytes(int width, int height, Bitmap.Config config){
long pixels=width*height;
switch(config){
case ALPHA_8: // 1 byte per pixel
return pixels;
case ARGB_4444: // 2 bytes per pixel, but depreciated
return pixels*2;
case ARGB_8888: // 4 bytes per pixel
return pixels*4;
case RGB_565: // 2 bytes per pixel
return pixels*2;
default:
return pixels;
}
}
次に、アプリが使用しているメモリの量と利用可能な量をクエリします。おそらくその半分を取り、画像キャッシュの合計サイズをそれ以下に維持しようとします。これは、リストから古い画像を単純に削除 (逆参照) することによって行われます。この制限に対して、リサイクルではありません。ビットマップがキャッシュから参照解除され、どのビューでも使用されていない場合は、ガベージ コレクターにビットマップをクリーンアップさせます。
/**
* Calculates and adjusts the cache size based on amount of memory available and average file size
* @return
*/
synchronized private int calculateCacheSize(){
if(this.cachedBitmaps.size()>0){
long maxMemory = this.getMaxMemory(); // Total max VM memory minus runtime memory
long maxAllocation = (long) (ImageCache.MEMORY_FRACTION*maxMemory);
long avgSize = this.bitmapCacheAllocated / this.cachedBitmaps.size();
this.bitmapCacheSize = (int) (maxAllocation/avgSize);
}
return this.bitmapCacheSize;
}
を使用しないことをお勧めします。recycle()
断続的な例外が多数発生し (ファイナライズされたように見えるビューが再利用されたビットマップにアクセスしようとした場合など)、一般的にバグがあるようです。