2012-06-18 74 views
3

所以我有一個臭名昭着的OOM錯誤引起的大位圖。但我已經設法解決大部分問題。當我點擊後關閉應用程序,然後立即啓動應用程序時,剩下的唯一問題就發生了。然後,該應用程序將崩潰給我一個OOM(內存不足)錯誤。如果我點擊回家,這不會發生。安卓應用崩潰內存重啓

這是怎麼發生的?我的猜測是,GC還沒有完成清理工作,現在我開始啓動它,而舊數據仍然處於周圍。當然這不是一個新的應用程序,所以舊版本和新版本都會受到相同的應用程序內存限制。

在這個問題上的任何投入和可能的解決方案將是偉大的。

什麼,我tryed:

位圖的所有下載我用:

BitmapFactory.Options op = new Options(); 
op.inPurgeable = true; 
bmImg = BitmapFactory.decodeStream(is,null,op); 

使圖像尺寸更小寬x高(以KB大小大致相同) 。 < - 這解決了問題,所以我有一個後備的解決方案,除非有一個人在那裏有一個超級的解決方案:)

錯誤日誌的摘錄:

06-25 04:29:28.917: E/AndroidRuntime(8819): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.content.res.Resources.loadDrawable(Resources.java:1713) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.widget.ImageView.<init>(ImageView.java:122) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.widget.ImageView.<init>(ImageView.java:112) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  ... 23 more 

編輯: 於是兩個事情爲我解決這個問題。

  1. 清除我的數據庫,並將我的主要活動ondestroy()中的大圖像設置爲null。
  2. 使大圖像變小。

但是,這只是引發同樣的基本問題,如果調用onDestroy(),爲什麼我的活動沒有正確關閉,然後打開一個新的?此外,我看到我的活動在關閉後很長一段時間內繼續運行。這可能與問題有關嗎?我如何查明原因?

編輯2:culprint似乎是我的LruCache。我使用了ondestroy()中未清空的靜態lrucache。當應用程序重新啓動時,lrucache中的所有圖像仍然存在,這會導致問題。我仍然想知道爲什麼這只是在重新啓動時出現問題?當我在關閉它之前回到我的主要活動時,這不應該成爲一個問題嗎?

+0

這可能是在位圖解碼的大文件大小,所以你可以嘗試這個帖子的位圖大尺寸文件解碼解決方案:http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue -while-loading-an-image-to-a-bitmap-object/823966#823966歡迎! – Dinesh

回答

0

culprint似乎是我的LruCache。我使用了ondestroy()中未清空的靜態lrucache。當應用程序重新啓動時,lrucache中的所有圖像仍然存在,這會導致問題。我仍然想知道爲什麼這只是在重新啓動時出現問題?當我在關閉它之前回到我的主要活動時,這不應該成爲一個問題嗎?

不過,我這個問題的臨時/永久性修復是清理ondestroy()中的所有靜態引用,但也使用較小尺寸的圖像。這似乎解決了我所有的問題,因爲我也無法找到任何內存泄漏。

1

嘿請我在同一個問題的答案:bitmap size exceeds Vm budget error android

而且還總是試圖同時處理位圖處理像這樣使用最多選項:

 final Options options = new Options(); 
     options.outHeight = (int) scaleHeight; // new smaller height 
     options.outWidth = (int) scaleWidth; // new smaller width 
     options.inScaled = true; 
     options.inPurgeable = true; 

     // to scale the image to 1/8 
     options.inSampleSize = 8; 
     bitmap = BitmapFactory.decodeFile(imagePath, options); 

這可能會解決你的問題。

+0

我已經在inPurgeable中使用。 inSampleSize會降低質量,這不是一個選項。我需要這個圖像的大小。 – Warpzit

+0

如果圖像的大小非常大,例如2到3 MB,那麼加載圖像將導致此錯誤。圖像的大小是多少?檢查你的代碼是否有內存泄漏,這也可能是問題所在。 – Shrikant

+0

mdpi是900 x 900像素和〜93kb,如果圖像不是很大,則hdpi會調整爲 – Warpzit

2

我遇到了同樣的問題,通過強制關閉過程解決了這個問題。這可以通過覆蓋onDestroy()來完成。使用這個:

@Override 
public void onDestroy(){ 
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses(); 
    for (int i = 0; i < pids.size(); i++) { 
     ActivityManager.RunningAppProcessInfo info = pids.get(i); 
     if (info.processName.equalsIgnoreCase(context.getPackageName())) { 
      android.os.Process.killProcess(info.pid); 
     } 
    } 
    super.onDestroy(); 
} 
+0

這可能會起作用,但我想我會嘗試查找導致我的應用程序無法正常關閉的參考。 – Warpzit

+0

經過一番閱讀(其中包括commonsware)我不會在這個方向去。這可能會導致其他各種麻煩。 – Warpzit

+0

我明白你的顧慮,但我還沒找到更好的選擇。 –