转自:https://testerhome.com/topics/579

 

首先说一下,在程序没有崩溃的时候如何抓取heap快照。
这个大家应该都知道,在ddms中自带此功能。

 

(转)OutOfMemory时抓取heap 快照
 


见上图
首先我们选中一个进程,然后点击 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.

相关文章:

  • 2021-11-28
  • 2022-02-10
  • 2022-12-23
  • 2021-07-29
  • 2022-02-08
  • 2021-08-28
  • 2022-02-22
猜你喜欢
  • 2022-12-23
  • 2021-09-22
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-22
相关资源
相似解决方案