2011-09-08 52 views
1

我正在檢查我的應用程序的內存泄漏/使用情況,並發現了一些奇怪的東西,目前爲止我只在Android 1.6和2.1中看到過。點擊左右在應用程序一點,我運行「亞行外殼dumpsys meminfo中」我的應用程序後,我看到以下內容:Android內存使用和內存中的對象未在1.6和2.1中發佈

DUMP OF SERVICE meminfo: 
Applications Memory Usage (kB): 
Uptime: 34639912 Realtime: 153524709 

** MEMINFO in pid 5778 [com.app.myapp] ** 
        native dalvik other total 
      size: 14336  4679  N/A 19015 
     allocated: 13971  4139  N/A 18110 
      free:  280  540  N/A  820 
      (Pss):  2986  4181 13491 20658 
    (shared dirty):  972  3948  620  5540 
    (priv dirty):  2876  3224 10976 17076 

Objects 
      Views:  545  ViewRoots:  4 
    AppContexts:  32  Activities:  31 
      Assets:  2 AssetManagers:  2 
    Local Binders:  43 Proxy Binders:  79 
Death Recipients:  2 
OpenSSL Sockets:  1 

SQL 
      heap:  91   dbFiles:  0 
     numPagers:  4 inactivePageKB:  0 
    activePageKB:  0 

Asset Allocations 
    zip:/data/app/com.app.myapp.apk:/resources.arsc: 119K 

正如你所看到的,沒有什麼是得到釋放/ GC'd,該活動是堆放,AppContexts等,直到應用程序崩潰與OutOfMemoryError。這在2.2+上不會發生。

任何人都可以告訴我爲什麼會發生這種情況嗎?我有一種感覺,它要麼是簡單的,要麼是我的應用程序有點奇怪,但是我爲什麼會發生這種情況而感到不知所措。

僅供參考,我已經在1.6和2.1模擬器以及我的G1運行1.6中轉載了此內容。最近用戶的崩潰報告也顯示了這一點,他們在Droid Eris上運行2.1。如果需要更多的細節/代碼來幫助解決這個問題,請告訴我。

## UPDATE ##

感謝來自MOMO的信息,我可以跟蹤了一些內存泄漏問題,這大大削減活動/ AppContexts的,將顯示在對象的量meminfo列表。

該數字現在降低到我的應用程序中實際活動的數量左右,因此在較早版本的Android上它似乎會顯示您的應用程序消耗的對象總量。在新版本上它不會,儘管這可能僅僅是我的測試設備上的情況。

+0

的工具目錄中找到這仍然是相同的應用程序(我的同伴釣魚)?如果是的話,重現的步驟是什麼? – momo

+0

是的。基本上只需點擊從活動到活動,你就會開始看到堆積的物體。據我所知,似乎只發生在1.6和2.1中。 – hooked82

+0

在下面的答案中,您對MAT進行了評論。您是否嘗試了以下步驟:1.查看實例數量是否爲卡住的活動。 2.查看GC的根路徑?如果活動數量堆積如常,我通常會這樣做,特別是如果GC的根路徑不是ViewRoot。如果它不是ViewRoot,那麼其他東西就會阻止你需要切割參考。如果您仍然需要調試,我可以詳細解答這個過程。我無法在您的應用上專門運行MAT,因爲它來自市場 – momo

回答

9

爲了清楚瞭解活動舉行的原因,我通常使用MAT,然後查看活動中卡住的GC根的路徑。

我已經創建了一個簡單的項目,它加載簡單的TestActivity爲了說明這個過程。下面是它的代碼:


package com.so; 

import android.app.Activity; 
import android.os.Bundle; 

public class TestActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 
} 

步驟如下:

  • 傾倒在通過DDMS「轉儲HPROF文件」功能
  • 運行過程中HPROF假設你已經安裝了MAT,這應該調出MAT屏幕
  • 現在根據您的活動包過濾,對於上面的示例,它是com.so.截圖這個過程如下:

MAT Histogram Screen

  • 現在你想看看這個有GC的清晰路徑。你這樣做,通過右鍵單擊活動並顯示所有的引用,如下圖所示:

Show all references

您應該看到您的活動是由com.android.internal.policy.impl.PhoneWindow $ DecorView和舉行沒有別人了。如果是這種情況,那麼你沒問題,這個Activity最終將被GC回收。

現在我會做改變我的班,包括一個靜態變量,將舉行自己的實例:


package com.so; 

import java.util.ArrayList; 

import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 

public class TestActivity extends Activity { 
    static ArrayList memoryLeakList; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // create a deliberate static list to cause the leak 
     TestActivity.memoryLeakList = new ArrayList(); 
     TestActivity.memoryLeakList.add(this); 
    } 
} 

如果我運行代碼HPROF用同樣的步驟,我現在明白了活動的參考由ArrayList和不com.android.internal.policy.impl.PhoneWindow $ DecorView舉行標誌着有泄漏的可能性,如果我不收拾陣列現在

Memory Leak caused by ArrayList

,你不必爲每個A都這樣做活動,我會做什麼只是簡單地運行應用程序,然後轉儲HPROF。然後您將再次通過包進行過濾以獲取應用程序的快照。在初始柱狀圖中,您應該對在DDMS中點擊GC按鈕後有多個實例數量超過1的活動持懷疑態度,並從此處開始調查。

還要說明一點,在我的手機2.1,我無法通過DDMS得到HPROF,所以我做到了通過以下步驟模擬器:

  • 轉到./adb殼
    • 輸入ps讓您的應用進程的PID
    • 類型殺-10,你應該在你的logcat看到它是傾內存/數據/雜項
    • 如果你得到許可被拒絕,請務必閱讀/通過執行chmod 777數據在該文件夾上寫入/ misc在
  • 由於HPROF是基於Dalvik的拉動使用DDMS文件資源管理器在Eclipse或拉命令
  • 要麼產生的HPROF,爲了與內存分析工具,使用它,你需要把它通過先轉換hprof-conv在你的Android SDK安裝

    Run ./hprof-conv [source dump] [target dump]
+0

謝謝莫莫!一回到我的系統,我就會看看這個。 – hooked82

+0

我看了一個堆轉儲和我的一個活動,它顯示的路徑爲:活動> mContext(com.android.internal.policy.impl.PhoneWindow $ DecorWindow)> mView(android.view.ViewRoot)> this $ 0(android.view。ViewRoot $ 1本地堆棧。這是一個潛在的泄漏,我從哪裏去? – hooked82

+0

@ hooked82這看起來不像一個。如果你轉到其他Activity,在DDMS中點擊gc按鈕並採取另一個hprof,Activity是否消失?我們應該關注實例數量持續上升的活動,然後選擇其中一個並運行相同的過程 – momo