簡體   English   中英

如何找到內存泄漏的根?

[英]How to find root of memory leaks?

我的應用程序基本和圖像編輯器。 有一個歡迎頁面可以打開主要活動。 如果在主要活動正在運行時方向發生變化,則內存消耗量會翻倍並保持不變。 如果我關閉主要活動,請返回歡迎活動並再次啟動主要活動同樣的問題不會發生。 我認為所有這些都表明內存泄漏,我已經調查了自己,但無法找到為什么應用程序泄漏內存。 我正在使用應用程序上下文,我的應用程序中沒有靜態字段。 我試圖轉儲堆並用MAT分析它,但我找不到任何好的東西。 我希望有人能告訴我正確的方向,找到內存泄漏的根源或其他可能的問題解釋。

Google I | O 2011會議演示中介紹了此特定方案。 我建議觀看演示文稿,因為它可以幫助您更好地使用MAT找到問題。

請記住,在JVM中(甚至在我不能相信它不是像Davlik這樣的JVM中),您使用的許多項目並不完全在您的控制之下。 所以,正確的方法是找到一種方法來驗證你的代碼沒有內存泄漏,然后你會知道如果內存開花,它可能是一些外部子系統,或者是應用程序實際內存需求的某些預期結果。

根據您的描述,很容易就是顯示渲染只是為每個屏幕方向保留一個延遲構建的緩存內存緩沖區。

我只提到這一點,因為你已經(從你的帖子中)比較了堆轉儲,如果堆沒有顯示對象累積的趨勢,那么它很可能是庫實現中包含的一些項目。 我知道這是一個非常一般的經驗法則,並不適用於大多數程序(因為它們可能包含真正的內存泄漏),但是當其他選項耗盡時,可能會調查它。

如果你真的想驗證一個特定的庫是否保留了屏幕方向的緩存副本,你總是可以編寫一個小的“測試”程序,它缺少所有混淆因素(比如程序的其余部分),看看如何它在屏幕方向轉換時執行。

就使用VisualVM而言,它非常適合檢測用戶空間內存泄漏; 但是,由於它運行在不同的體系結構和實現上,因此可能會錯過特定於平台的庫問題。

我的應用程序遭受了嚴重的泄漏,雖然我發現MAT工具很有用,但我發現主要原因是我沒有正確管理活動堆棧。 我認為最有用的檢查方法是從命令行使用:

adb shell dumpsys meminfo your.package.name

你會得到像這樣的輸出

adb shell dumpsys meminfo your.package.name
Currently running services:
  meminfo
-------------------------------------------------------------------------------
DUMP OF SERVICE meminfo:
Applications Memory Usage (kB):
Uptime: 150876 Realtime: 150875

** MEMINFO in pid 253 [your.package.name] **
                    native   dalvik    other    total
            size:     5404     4103      N/A     9507
       allocated:     5294     3110      N/A     8404
            free:      101      993      N/A     1094
           (Pss):     2346     3737     2198     8281
  (shared dirty):     1964     4644     1480     8088
    (priv dirty):     2204     1856      956     5016

 Objects
           Views:       30        ViewRoots:        2
     AppContexts:        3       Activities:        2
          Assets:        2    AssetManagers:        2
   Local Binders:       13    Proxy Binders:       16
Death Recipients:        2
 OpenSSL Sockets:        0

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

檢查活動計數並在更改方向時觀察堆大小更改等。確保您沒有啟動已在運行的活動的副本。 您可以使用您為啟動活動時的意圖標記來控制堆棧。

VisualVM http://visualvm.java.net/
它是在1.6K的某個版本的JDK發行版中

如果您的應用程序是圖像編輯器,並且您看到了這種類型的行為,那么我希望您不會回收Bitmap內存(請參閱http://developer.android.com/reference/android/graphics/Bitmap.html#recycle% 28%29 )。

當您的方向發生變化並且活動被破壞時,您需要找到您的視圖正在使用的任何大型位圖,然后調用它們上的recycle或使用onRetainNonConfigurationInstance方法(請參閱http://developer.android.com/reference/android/ app / Activity.html#onRetainNonConfigurationInstance%28%29 )將其傳遞給新的Activity實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM