• (转)OutOfMemory时抓取heap 快照


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

    首先说一下,在程序没有崩溃的时候如何抓取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(HPROF_FILE_PATH);

    使得我们可以自己控制抓取heap快照的时机
    OutOfMemoryError是系统级别的错误,所以一般情况下不该捕获它。
    万一有人捕获了,并且重新抛出了一个调用了initCause方法的异常,我们也应该截获它,然后修正bug,而不是掩藏它。

    我们在这里只是需要抓取内存快照,干完活之后要记得把throwable交给系统来处理
    Java代码 收藏代码
    mDefaultHandler.uncaughtException(thread, throwable);

    当然,我们在这个地方实际上也可以屏蔽掉force close对话框,很神奇吧。。。

    结尾顺便说一下,如何查看android对应用的内存限制
    每款手机对应用的限制都是不一样的,毕竟硬件不同,我们可以使用如下方式来查看单独的应用可使用的最大内存:

    adb shell getprop | grep heap  

    输入命令之后回查到上述几个结果

    更改上述参数可以在build.prop修改
    build.prop在system下,pull出来修改后再push回去,reboot即可

    我们可以根据这个来估计heap的大小,检查sd卡剩余空间是否够用。

    转贴请保留以下链接
    本人blog地址
    http://su1216.iteye.com/
    http://blog.csdn.net/su1216/

  • 相关阅读:
    Hadoop入门进阶课程12--Flume介绍、安装与应用案例
    Hadoop入门进阶课程11--Sqoop介绍、安装与操作
    Hadoop入门进阶课程10--HBase介绍、安装与应用案例
    Hadoop入门进阶课程9--Mahout介绍、安装与应用案例
    Hadoop入门进阶课程8--Hive介绍和安装部署
    Hadoop入门进阶课程7--Pig介绍、安装与应用案例
    zookeeper启动失败,但是状态显示已启动的原因
    微信小程序企业给零钱打款 提示未配置api发起,请查看产品中心企业付款配置
    java利用反射交换两个对象中的字段相同的字段值
    centos上 小程序部署 nginx+https+ssL 提示错误:对应的服务器 TLS 为 TLS 1.0 ,小程序要求的 TLS 版本必须大于等于 1.2
  • 原文地址:https://www.cnblogs.com/melody-emma/p/4913952.html
Copyright © 2020-2023  润新知