2014-05-05 24 views
0

我有一個應用程序,顯示了很多活動,每個顯示一個位圖,適合100%的屏幕寬度,通常超過100%的高度。Bitmap OutOfMemoryError即使使用回收()

當你觸摸屏幕,新的活動被創建,並且在之前的活動被稱爲光潔度和回收爲位圖:

public void clean() { 
    if(this.myBitmap != null){ 
     Log.d(DEBUG_TAG, " Cleaning "+this); 
     this.myBitmap.recycle(); 
     this.myBitmap=null; 
     System.gc(); 
    } 
} 

的問題是,所需的內存被不斷擴張和當我推出超過12-13的活動,這些消息在被logcat中顯示:

05-05 16:03:02.909: I/dalvikvm-heap(24794): Clamp target GC heap from 65.790MB to 64.000MB 
05-05 16:03:02.969: D/dalvikvm(24794): GC_EXPLICIT freed 71K, 5% free 59008K/61680K, paused 2ms+13ms, total 55ms 
05-05 16:03:03.559: I/dalvikvm-heap(24794): Clamp target GC heap from 67.197MB to 64.000MB 
05-05 16:03:03.569: D/dalvikvm(24794): GC_EXPLICIT freed 418K, 2% free 60521K/61680K, paused 3ms+28ms, total 109ms 

的一些活動經過我得到這個崩潰:

05-05 16:03:05.049: E/AndroidRuntime(24794): java.lang.OutOfMemoryError 
05-05 16:03:05.049: E/AndroidRuntime(24794): at android.graphics.Bitmap.nativeCreate(Native Method) 
05-05 16:03:05.049: E/AndroidRuntime(24794): at android.graphics.Bitmap.createBitmap(Bitmap.java:809) 
05-05 16:03:05.049: E/AndroidRuntime(24794): at android.graphics.Bitmap.createBitmap(Bitmap.java:786) 
05-05 16:03:05.049: E/AndroidRuntime(24794): at android.graphics.Bitmap.createBitmap(Bitmap.java:718) 

我不知道是怎麼回事錯了,我在做回收()位圖,並且還我tryed有和沒有的System.gc(),在這兩種情況下我得到了崩潰

+0

您是否嚮應用程序添加了largeHeapSize標誌? –

+0

mmmm謝謝deathember似乎使用這已經改進了我的應用程序,但我認爲這不是最終的解決方案 – NullPointerException

+0

讓我來解釋一下。當你在你的記憶中使用大的位圖時,你會給一個OME。更多的位圖 - 更多機會獲得OUME。添加標誌不是一個壞的方式,因爲Android讓你獲得最大的堆大小來將你的對象加載到內存中。谷歌它爲羅馬人的機器人的內存管理。谷歌推薦你使用這個標誌。但你有另一種方式。看看你的代碼,也許你可以改進它,也許這可以修復你的OME。 –

回答

1

使用DDMS搶堆轉儲並使用Eclipse Memory Analyzer(內置於Eclipse ADT或可以獨立運行)對轉儲進行一些分析。你所尋找的是你分配但未被釋放的對象。一種可能是你正在泄漏活動。你說在啓動12-13活動後發生OOM錯誤。一次只能看到其中一個活動,因此您可以從onPause()onStop()方法中的暫停活動中釋放內存。再次,分析堆轉儲會給你一個很好的想法,即堆內存正在吃掉。

僅供參考 - Bitmap#recycle()僅在薑餅和低級設備上非常必要。在較新版本的OS位圖存儲在堆上,並像其他對象一樣被垃圾收集。請參閱本文檔的「管理Android 2.3.3及更低版本上的內存」部分:https://developer.android.com/training/displaying-bitmaps/manage-memory.html

2

它的一個known bug,它不是因爲大文件。由於Android會緩存Drawables,因此在使用少量圖像後會出現內存不足的情況。但我找到了替代方式,通過跳過android默認緩存系統。

Soultion: 創建資產繪製文件夾,移動圖像,以「繪製」文件夾中的資產,並使用以下函數來獲取BitmapDrawable

public static Drawable getAssetImage(Context context, String filename) throws IOException { 
    AssetManager assets = context.getResources().getAssets(); 
    InputStream buffer = new BufferedInputStream((assets.open("drawable/" + filename + ".png"))); 
    Bitmap bitmap = BitmapFactory.decodeStream(buffer); 
    return new BitmapDrawable(context.getResources(), bitmap); 
} 

Refrence:https://stackoverflow.com/posts/6116316/revisions

也是在清單文件中添加以下的行

android:largeHeap="true"