美文网首页
ADB dumpheap + MAT 分析内存泄漏

ADB dumpheap + MAT 分析内存泄漏

作者: 河里的枇杷树 | 来源:发表于2023-10-18 19:57 被阅读0次

    废话不多说直接说流程

    1. 通过adb dump 内存快照
    adb shell am dumpheap {进程名} {存储路径} 
    
    例如:
    adb shell am dumpheap nova.priv.terminal.player.PlayService /sdcard/1.hprof
    
    1. 导出到电脑上
    adb pull /sdcard/1.hprof C:\Users\...\1.hprof
    
    • 导出以后我们会得到1.hprof文件,但是这个不是mat工具用到的标准文件。我们需要使用sdk自带的hprof-conv.exe(platform-tools文件夹下) 工具进行转换,转换以后我们就得到了1_mat.hprof文件
    转换mat标准文件
    命令:hprof-conv -z src dst
    例如:hprof-conv -z 1.hprof 1_mat.hprof
    
    image.png
    • 进入Histogram 页面有我们在红框位置输入我们想要找的类,然后右键选择merge shortest paths to Gc roots然后在选择exclude all phantom/weak/soft etc.references选项

      image.png
    • 就得到了如下的引用图,从图中我们分析出 loginActivity是被inputMethodManager所引用(这其实是android系统的一个bug),所以我们主要将两者之间的联系给断开就行,解决方法如下


      image.png
    • 使用反射的方式将引用的view置为null

            InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            try {
                //获得 所有属性  getField->public  以及父类
                Field mCurRootViewField = InputMethodManager.class.getDeclaredField("mCurRootView");
                //设置允许访问权限
                mCurRootViewField.setAccessible(true);
                // 对象
                Object mCurRootView = mCurRootViewField.get(im);
                if (null != mCurRootView){
                    Context context = ((View) mCurRootView).getContext();
                    if (context == this){
                        //破怪gc 引用链
                        mCurRootViewField.set(im,null);
                }
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    

    相关文章

      网友评论

          本文标题:ADB dumpheap + MAT 分析内存泄漏

          本文链接:https://www.haomeiwen.com/subject/mppcidtx.html