随笔 - 148  文章 - 3  评论 - 2  阅读 - 11万

使用AndroidStudio提供的Android Profiler工具和mat进行内存泄漏分析

利用 Android Studio 查看内存

返回目录
返回目录

准备

1)Android 完整代码

2)真机

 

1. Profile APP

打开 Android Studio,在右上角,找到 Profile 'app' 的 icon。如果手机上不能自动打开,则要手动打开 APP。完成后,会看到如下图所示的 相关性能图示

APP内切换相关页面,可以看到相关性能的动态变化

 

 

2. Dump Java Heap

选择"Memory" -> 点击 “Force Garbage Collection” -> 点击“Dump Java Heap”

 

 

3. 分析

dump 完成后,点击左侧的 Heap Dump -> 在 Heap Dump 的下拉框后面选择“app heap” 及“Arrange by package”

 

 

 

--------------------------------- 以下未验证 ---------------------------------

当堆栈信息获取完成后,会弹出如下框,我们将排序方式选为 Arrange by package(好定位我们自己的代码),找到我们的代码后我们真的发现,应该已经被回收了的LoginActivity还占用这内存。但是为什么没有被销毁,还有那些对象引用着他。这时我们就需要点击位置为3的地方,导出.hprof文件进行具体分析了

image.png

 

  • 导出以后我们会得到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();
            }
    posted on   bruce_he  阅读(713)  评论(0编辑  收藏  举报
    编辑推荐:
    · 记一次.NET内存居高不下排查解决与启示
    · 探究高空视频全景AR技术的实现原理
    · 理解Rust引用及其生命周期标识(上)
    · 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
    · 没有源码,如何修改代码逻辑?
    阅读排行:
    · 分享4款.NET开源、免费、实用的商城系统
    · 全程不用写代码,我用AI程序员写了一个飞机大战
    · MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
    · 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
    · 上周热点回顾(2.24-3.2)
    < 2025年3月 >
    23 24 25 26 27 28 1
    2 3 4 5 6 7 8
    9 10 11 12 13 14 15
    16 17 18 19 20 21 22
    23 24 25 26 27 28 29
    30 31 1 2 3 4 5

    点击右上角即可分享
    微信分享提示

    目录导航