2011-11-27 38 views
1

我得到'java.lang.OutOfMemoryError:位圖大小超過VM預算'錯誤...我在做什麼是,我從服務器下載〜50圖像並將它們存儲在內存中。再次 - java.lang.OutOfMemoryError:位圖大小超過VM預算

當我第一次看到這個問題,我優化我們的圖像只下載縮略圖(50 JPEGS,〜12kB,大小160x240px),我開始通過調用Bitmap.recycle(),只要我不需要它們就釋放它們。一切正在更新的手機,其中過程可以得到32MB,但在最大16MB的舊手機不能。

所以我的問題是:

  • 它是正確的,所有的進程都僅限於在舊手機32MB或更小(即內存調用Runtime.getRuntime()maxMemory()調用返回)這個內存是用於Dalvik,框架,應用程序和數據的嗎?

  • 我們可以在應用程序中使用更多內存,然後返回數量Runtime.getRuntime()。maxMemory()

  • 我應該如何優化圖像 - 它們現在非常小...我應該開始將它們交換到內部閃存/ SD?只要他們在GridView控件顯示我保持他們的記憶...

我感謝所有幫助 - 我經歷了類似的線程就在這裏和做了什麼我已經看到有...但它仍然是不夠的......


編輯更新

我加了這些意見後weakwire答案。

•在我的情況下,我下載了50張圖像,並將它們全部存儲在內存中的位圖對象中。見下面爲什麼我這樣做。

•內存佔用多少內存位圖對象?它是否以原始格式存在意味着如果圖像是160x240x24bpp它在內存中佔用~115 kB,那麼50 images are ~6MB這是正確的嗎?

•我也讀到圖像是不是我的進程堆的一部分,但他們都算,所以使用maxMemory(),totalMemory(),freeMemory()不能真正幫助。 這是正確的嗎?

•我的應用程序UI具有完整的自定義圖形(60個PNG文件,在draw9pacth格式很多人)

•我有24/32 MB的設備沒問題,我的問題只有16個MB的設備

•只要我下載所有50張圖像並將它們存儲到內存中,我就會在2列寬度中顯示它們GridView。我想爲此我需要保留堆上的所有圖像(保存到內部閃存,我認爲這不是解決方案)。 這是正確的假設嗎?

•當我初始化應用程序並加載用戶界面時,我可以看到我有448kB的可用內存分配了整個16384kB預算的5459kB。我假設我不能真正使用整個16384kB +,如果我理解正確的話我從maxMemory(),totalMemory(),freeMemory()看不到有多少已經加載的圖像佔用,因爲dalvik-vm沒有'看見'這堆。假設〜2M已經被使用,我可以使用高達〜14MB,我有5.5MB左右,所以我可以很容易地與內存中的50個圖像碰到OOM問題... 這是正確的計算?

我肯定會看看建議的視頻 - 它看起來不錯 - 但weakwire,請儘量回答我的問題......感謝您的支持和您的時間!

+0

http://stackoverflow.com/questions/2131947/android-memory-allocation – confucius

回答

2

android:largeHeap =「true」是不可能的。如果沒有正確完成,你將有一個非崩潰但慢的應用程序。

32MB VM很大。許多現代手機仍然使用12MB或16MB。越大!=越好。

它並不重要放置圖像的位置。唯一值得考慮的是如果他們在虛擬機中。

否Runtime.getRuntime()。maxMemory()是您可以使用的MAX內存。

位圖是豐滿的對象(只要它的像素引用不是位圖對象本身)。如果不能正確解除分配,則GC無法收集它們,並且會出現OutOfMemoryError。

現在爲你的情況。 5MB的圖像不應該導致OOME。你有一個內存泄漏或另一個大的阻塞對象(可能是大背景圖像)。你應該檢查MAT和this video。有一些方法可以告訴垃圾收集器收集位圖,但您認爲可以輕鬆避免的問題。圖像的5MB就好了,可以是易於管理。(你不需要顯示所有50一次?你?)

注意你的編輯後

I have also read that images are not part of my process heap, but they are counted, so using the maxMemory(), totalMemory(), freeMemory() cannot really help. Is that correct?

No.Images是部分堆但未在MAT和其他工具中顯示。我認爲它們僅在3.2以後纔可見,但位圖在那裏。

As soon as I download all 50 images and store them into memory I show them in the 2 columns width GridView. I think for this I need to keep all images on the heap (saving to internal flash I think is not solution there). Is that correct assumption?

沒有這個假設是不正確的,這個假設是什麼導致了問題。

爲什麼你需要他們所有的堆?您可以在存儲設備(SD或內部存儲器緩存)中使用iamges的滯後用戶界面。如果您不確定如何在沒有懶惰加載的情況下處理這些圖像,則必須LazyLoad您的圖像。您應該檢查一些流行圖像的代碼(向下)加載器,看他們如何處理引用以及他們的緩存系統是如何組織的。你也可以使用其中之一

+0

感謝您的意見,我真的很感激這一點。我花時間和主要更新我的問題,使其更具體。我可以請你再看一遍,並試圖回答我的一些問題嗎?非常感謝您的活動。 – STeN

+0

更新了我的答案 – weakwire

+0

延遲加載的內存肯定是必要的 - 我將不得不弄清楚如何將它與我的自定義GridView適配器放在一起...謝謝 – STeN

相關問題