android OutOfMemory時抓取heap快照

來源:互聯網
上載者:User

(這裡不教你如何分析heap快照,只說明如何在關鍵時候抓取)
首先說一下,在程式沒有崩潰的時候如何抓取heap快照。
這個大家應該都知道,在ddms中內建此功能。


首先我們選中一個進程,然後點擊 Update Heap按鈕(小綠蟲子旁邊的按鈕),這時就能看到heap使用方式
如果想取出快照詳細分析,我們可以點擊 Dump HPROF File按鈕,儲存到電腦上面。使用android-sdk/tools/hprof-conv這個工具把檔案轉換一下,之後用MAT分析即可。
[java]
hprof-conv '/home/su1216/data.hprof' '/home/su1216/data_ok.hprof' 
這時MAT能直接開啟data_ok.hprof檔案。


如果想要OOM時的記憶體快照該怎麼辦,我們總不能緊盯著手機的同時再盯著電腦,OOM出現的瞬間抓取記憶體快照,這顯然是不現實的。
如果OOM並不經常複現,那麼我們會錯過很多修改bug的機會,浪費很多時間。

下面給大家一種抓取OOM時的heap快照的方法
由於OOM時的heap快照較大,所以抓取的記憶體快照我選擇儲存到sd卡中,因此要有寫入外部儲存的許可權
[xml] 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
然後我們需要實現UncaughtExceptionHandler這個介面
記得要設定未捕獲異常的Handler,設定為自己。
當出現了異常的時候,uncaughtException方法會被調用,所以如果我們可以在這裡抓取記憶體快照。
[java]
import java.lang.Thread.UncaughtExceptionHandler; 
 
import android.os.Debug; 
import android.os.Environment; 
import android.util.Log; 
 
public class CrashHandler implements UncaughtExceptionHandler { 
 
    public static final String TAG = "CrashHandler"; 
    private Thread.UncaughtExceptionHandler mDefaultHandler; 
    private static final String OOM = "java.lang.OutOfMemoryError"; 
    private static final String HPROF_FILE_PATH = Environment.getExternalStorageDirectory().getPath() + "/data.hprof"; 
 
    private static CrashHandler sCrashHandler; 
 
    private CrashHandler() {} 
 
    public synchronized static CrashHandler getInstance() { 
        if (sCrashHandler == null) { 
            sCrashHandler = new CrashHandler(); 
        } 
        return sCrashHandler; 
    } 
 
    public void init() { 
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); 
        Thread.setDefaultUncaughtExceptionHandler(this); 
    } 
 
    public static boolean isOOM(Throwable throwable){ 
        Log.d(TAG, "getName:" + throwable.getClass().getName()); 
        if(OOM.equals(throwable.getClass().getName())){ 
            return true; 
        }else{ 
            Throwable cause = throwable.getCause(); 
            if(cause != null){ 
                return isOOM(cause); 
            } 
            return false; 
        } 
    } 
     
    public void uncaughtException(Thread thread, Throwable throwable) { 
        if(isOOM(throwable)){ 
            try { 
                Debug.dumpHprofData(HPROF_FILE_PATH); 
            } catch (Exception e) { 
                Log.e(TAG, "couldn’t dump hprof", e); 
            } 
        } 
 
        if (mDefaultHandler != null) { 
            mDefaultHandler.uncaughtException(thread, throwable); 
        } else { 
            android.os.Process.killProcess(android.os.Process.myPid()); 
            System.exit(1); 
        } 
    } 

最關鍵的代碼是這句
[java] 
Debug.dumpHprofData(<span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; line-height: 18px; text-align: left; background-color: rgb(250, 250, 250); ">HPROF_FILE_PATH</span>); 
使得我們可以自己控制抓取heap快照的時機
OutOfMemoryError是系統層級的錯誤,所以一般情況下不該捕獲它。
萬一有人捕獲了,並且重新拋出了一個調用了initCause方法的異常,我們也應該截獲它,然後修正bug,而不是掩藏它。

我們在這裡只是需要抓取記憶體快照,幹完活之後要記得把throwable交給系統來處理
[java] 
mDefaultHandler.uncaughtException(thread, throwable); 
當然,我們在這個地方實際上也可以屏蔽掉force close對話方塊,很神奇吧。。。

結尾順便說一下,如何查看android對應用的記憶體限制
每款手機對應用的限制都是不一樣的,畢竟硬體不同,我們可以使用如下方式來查看單獨的應用可使用的最大記憶體:
adb shell getprop | grep heap
[dalvik.vm.heapgrowthlimit]: [64m]
[dalvik.vm.heapsize]: [256m]
[dalvik.vm.heapstartsize]: [8m]
輸入命令之後回查到上述幾個結果
[dalvik.vm.heapstartsize]: [8m]:給進程分配的起始heap=8m
[dalvik.vm.heapgrowthlimit]: [64m]:進程最大可分配到64m
[dalvik.vm.heapsize]: [256m]:單個虛擬機器可分配的最大記憶體=256m

更改上述參數可以在build.prop修改
build.prop在system下,pull出來修改後再push回去,reboot即可


我們可以根據這個來估計heap的大小,檢查sd卡剩餘空間是否夠用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.