2012-01-26 32 views
5

SETUP:記憶與活動::內存不足

我有此應用程式,其具有沿直線路徑4周的活動,真正簡單的導航: A - >乙 - 「ç - > d

所有這些活動共享相同的背景圖像,並且都有一些常規按鈕,一個textview或一個edittext。所有這些都是在單獨的視圖xml文件中定義的。

背景是一個漸變,是沉重的。大約3 megs作爲一個未壓縮的位圖。

該應用什麼也不做的是,在它的唯一邏輯,是開始活動,並關閉這些按鈕點擊

我試圖用MAT找到內存泄漏,但未能發現任何東西。在我的應用程序中保留的最大尺寸是656(ko?),應用程序的總保留尺寸是1520(ko?),我找不到任何會被複制的對象。 它的方式完全違背dumpsys這說明27300(?KO)分配

問題:

  1. ,當我瀏覽的時候,我看到的背景大小增加了內存使用情況等同。
  2. 當我向下導航時,使用後退按鈕或完成命令關閉活動時,應用程序的內存使用量不會減少。
  3. 如果我從A到D然後返回到B並旋轉屏幕,則應用程序組將以OutOfMemory異常關閉。

問題:

更新:我想真正的問題是,爲什麼我有一個巨大的內存泄漏(5兆在時間)在凍結時間27megs應用程序的大小,我不能在MAT中看到它?

  1. 爲什麼Android會多次解壓縮相同的背景,每個活動一次?似乎效率低下。
  2. 是否有可能通過使用主題來克服這個問題,還是我會看到相同的「按活動分配1個背景」怪異?
  3. 爲什麼關閉時不能回收活動?
  4. 爲什麼MAT和dumpsys呈現不同的數字?

線索

在完全相同的時間,我有: dumpsys meminfo中:

Applications Memory Usage (kB): 
Uptime: 74006853 Realtime: 110962243 

** MEMINFO in pid 22683 [com.kayenko.sosadresse] ** 
        native dalvik other total 
      size: 20820  5767  N/A 26587 
     allocated: 18751  2901  N/A 21652 
      free:  312  2866  N/A  3178 
      (Pss):  1357  201 16782 18340 
    (shared dirty):  2264  1804  5456  9524 
    (priv dirty):  1280  116 16032 17428 

Objects 
      Views:  0  ViewRoots:  0 
    AppContexts:  0  Activities:  0 
      Assets:  2 AssetManagers:  2 
    Local Binders:  18 Proxy Binders:  16 
Death Recipients:  1 
OpenSSL Sockets:  0 

SQL 
       heap:  0   MEMORY_USED:  0 
PAGECACHE_OVERFLOW:  0   MALLOC_SIZE:  0 

而這種支配樹:

MAT Dominator tree

Thansk給任何人關於我是什麼的線索假設尋找。

回答

7

內存是Android中非常棘手的主題。

每個應用程序都會根據設備獲取堆內存限制。這個堆內存是dalvik內存加上本機內存,您可以將其視爲dumpsys meminfo結果中的總列。達爾維克內存處理除本地內存中分配的位圖以外的所有內容(對於Honeycomb之前的Android版本,這是正確的)。

說了這麼多,我只能回答大家的一些問題:

  1. 據我所知,Android將始終分配內存的位圖,即使它們是相同的。因此,就你而言,每個活動都爲你的背景分配內存。

  2. 我不知道它是否更好地處理主題,你必須嘗試。

  3. 一方面,當設備有足夠的內存來處理下一個活動時,活動不會被回收。當您按下後退按鈕時,每個活動都會從恢復的位置推到一堆。在Android需要更多內存的情況下,它會從釋放內存的堆中刪除一個活動(回到問題一,也許這是不共享內存的原因)。另一方面,您可以設置活動launchMode以更改此行爲(看看here)。

  4. 我認爲MAT不顯示本機內存數據。使用dumpsys meminfo的本地列來查看您爲Bitmap分配了多少內存。

我自己曾經有過處理OutOfMemory問題的困難時期。現在我有一個更清晰的想法 它是如何工作的,我能夠處理大文件而不會耗盡內存。我會強烈建議這兩個資源對我幫助很大:

祝你好運!

+0

謝謝哈維,這是非常豐富的。我已經查看了你給我的鏈接,但不幸的是沒有任何幫助。我不知道launchmode,必須承認我對它應該做的事情一無所知。我想我將不得不測試它,因爲文檔和往常一樣「缺乏」:) – Yahel

+1

我會將你的答案標記爲答案,因爲你實際上給了我4個答案中的3個:D – Yahel

0

當您銷燬活動時,您需要顯式回收用作背景的位圖。代碼將如下所示:

@Override 
protected void onDestroy() { 
    Drawable drawable = getView().getBackground(); 
    if (drawable instanceof BitmapDrawable) { 
     ((BitmapDrawable)drawable).getBitmap().recycle(); 
    } 
    drawable.setCallback(null); 
    getView().setBackgroundDrawable(null); 
    super.onDestroy(); 
} 

也許您需要爲嵌套視圖遞歸釋放資源,但它取決於您的佈局結構。這是一般情況下

+0

感謝您的輸入,遺憾的是,它完全沒有幫助。根據你的代碼,我的小部件都沒有bitmapdrawable,我也嘗試了這個頁面的代碼:http://www.alonsoruibal.com/bitmap-size-exceeds-vm-budget/,然後把它們混合使用儘可能激進,但無濟於事。 – Yahel

+0

我不同意。一旦沒有更多的引用,Dalvik會自動回收位圖。沒有必要手動執行此操作,因爲存在recycle()方法,所以您可以提前快速執行此過程並回收內存。 –

4

所以調查和哈維的幫助小時後這裏的結果:

問:爲什麼要解壓的Android多次相同的背景,每一次的活動?似乎效率低下。

答:雖然看起來合乎邏輯的方法是要求在活動中共享位圖,因爲我們使用的是內存很小的移動設備,但在Android中似乎並不存在。每次在不同的活動中使用位圖時,都將其解壓縮到本地內存。

問:是否有可能通過使用主題來克服這個問題,或者我會看到相同的「按活動分配一個位圖」奇怪嗎?

實驗結束後,使用主題消耗的內存與在佈局的xml中明確設置位圖所使用的內存量完全不同。這對我來說很奇怪,因爲造型是將屬性分組到同一個地方。

Q.關閉時爲什麼不收回活動?

答:嗯,我不知道,但我發現,這幾乎只在調試時纔給我OOM錯誤。從設備上啓動應用程序時,幾乎從未發生過。調試過程中的一個小故障?試用它之前,你鬆了5個小時測試一個zillion的東西。

問:爲什麼MAT和dumpsys呈現不同的數字?

答:哈維的答案是正確的,dumpsys meminfo顯示所有分配的內存(native + dalvik),而MAT僅顯示Dalvik。由於位圖像素在本機內存中分配,因此MAT不會看到它。這只是在Android 3.0之前,他們改變了分配方案,並使位圖的像素數據適合Dalvik。

問:我怎麼解決我的問題

答:首先,這可能不是一直存在問題而無法調試的時候。其次,要在安全方面我更換了梯度的形狀PNG,使用徑向漸變,在我活動的OnCreate使用的

getWindow().setFormat(PixelFormat.RGBA_8888); 
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER); 

要儘量避免條帶。我仍然會在某些設備上進行綁定,但我寧願使用綁定條形碼。