2013-06-11 23 views
16

我正在寫一個圖片庫應用程序,我一直在進入內存不足的錯誤。我緩存所有的圖像,但當我嘗試在圖像之間切換時發生問題真的很快。我假設應用程序分配內存比GC有時間釋放內存更快(因爲當我慢慢切換圖像時不會發生崩潰)。android:largeHeap =「true」約定?

敲我的頭靠在這個問題天后,我終於決定給largeHeap設置清單文件一試。在此設置之後,無論我在圖像之間切換多快,我的應用程序都不會再崩潰。

現在,我想知道是否有任何公約或一般準則,以使用largeHeap設置,因爲它可能如果說,一個記筆記的應用程序使用largeHeap就沒有太大的意義。一般來說,哪些應用程序適合largeHeap設置?

感謝

+0

順便說一句,如果您在確定不再使用位圖時立即調用'bitmap.recycle();',那麼該位圖內存的大部分將立即釋放。 (當GC解決它時,剩下的只是一個小物件。) – ToolmakerSteve

回答

23

一般來說,哪些應用程序是largeHeap設置一個很好的候選人?

問鼎在那裏你可以你爲什麼要強迫他們所有的其他應用程序的內存不足,證明用戶給你的堆空間豐厚的量。

就個人而言,我不認爲「一個圖片庫應用程序」的參賽資格。 AutoCAD,視頻編輯器等將符合資格。

關於您的內存管理問題,請確保您在API Level 11+上運行時使用inBitmapBitmapOptions,以便回收現有緩衝區而不是通過垃圾收集。特別是對於圖片庫,您可能有很多相當一致的縮略圖大小,回收現有的緩衝區將是一個巨大的好處。這可以幫助整體內存消耗(即,你真的內存不足)和內存碎片(即,你得到一個有足夠的堆空間的OutOfMemoryError,但沒有足夠大的分區,由於Android的frakkin'壓縮垃圾收集器)。

您也可以考慮查看現有的圖像緩存實現,例如Picasso的實現,以查看是否有一些提示可以學習(或可能只是重複使用)。

+0

謝謝你的回答!一個問題:我也在構建一個圖庫應用程序,但我已經在使用畢加索,並且仍然存在OutOfMemoryError。你認爲最好的做法是什麼?使用'largeHeap = true'可以解決這個問題。除了使用這個快速解決方案之外,你認爲還有其他的事情可以做嗎? – Karim

+3

@Cookiki:「你認爲最好的事情是什麼?」 - 弄清楚你真正的問題是什麼。你有內存泄漏嗎?你可不可以重複使用「位圖」對象?等等。 – CommonsWare

1

首先,確保你沒有加載比所需的更大的位圖:
Load a Scaled Down Version into Memory


然後,嘗試largeHeap之前,儘量釋放內存很快自己

如果你只要你確信你不會再使用位圖,然後大頭調用bitmap.recycle();位圖的內存將爲立即釋放。 (當GC接近它時,剩下的只是一個小物件。)


在較新的Android版本,有替代品(而不是recycle),可能是更有效的:
Managing Bitmap Memory

就個人而言,我還是用recycle時候,尤其是當我可能會加載不同大小的圖像,所以不能reuse現有的。另外,我發現在更換不同片段或活動時,舊媒體的「卸載」與新媒體的「加載」分開更容易:
由於離開舊片段,所有舊位圖I recycle(如果可以訪問從靜態字段設置爲null)。


根據經驗,是否使用largeHeap規則,是要考慮它後,你已經嘗試其它方法來減少內存使用。

代碼的應用程序,所以你可以再次關閉,仍然運行。

例如,monitor your memory usage如果內存很緊,請加載「縮小」位圖。如果給定圖像不在其設備的「視網膜」分辨率,用戶是否真的會注意到?

或者,如果它是一個較舊的較慢的設備,largeHeap會讓您的應用程序感覺無響應/生澀?如果是這樣,你可以進一步降低分辨率,或一次顯示較少的位圖

讓您的應用程序在各種情況下工作,沒有largeHeap [通過上述技術]。注意:通過分配一些「虛擬」位圖,你可以在緊張的內存上運行「force-test」,並在全局字段中保存對它們的引用,這樣它們就不會被釋放。

現在你可以評估的權衡,因爲它會影響您的應用程序:

當你打開largeHeap,大量使用你的應用程序 - 是否有地方現在是「較爲低迷」,或動畫「口吃」還是看起來不那麼流暢?請務必在至少一臺舊設備上進行測試,並在一臺高分辨率設備上進行測試。 由於堆較大,您可能會看到較長的GC時間。

或者您可能會得出結論:largeHeap對您而言效果很好,現在您可以自信地說它是您情況中的最佳選擇。