性能优化02_内存泄露分析及工具使用

Android性能优化汇总

一、Android Monitor

1 生成.hprof文件

Android Monitor是AndroidStudio自带工具,可以查看内存、网络、CPU使用情况,选定程序可以分析应用的资源使用,内存看CPU
在这里插入图片描述
在Memory窗口显示时,先点击几次GC(垃圾回收),内存稳定后,点击生成内存.hprof文件

在这里插入图片描述

2 分析

在打开.hprof文件的视图窗口中,选择appheap、Arrange by Package,找到自己的包,以及对应的类

在这里插入图片描述
下方视图:
Total Count 类对应对象的个数
Heap Count 堆内存中个数
Size of 物理大小
Shallow Size 对象本身占多大内存
Retained Size 释放后节省多少内存
右侧视图:
Instance:
Depth:深度
Shallow Size 对象实例大小
Dominating Size 对象管辖的内存大小

**注意:**工具本身不能解决内存泄露问题,而是帮助我们找到泄露的问题所在

3 查找步骤:

  • 查找引用了该对象的外部对象有那些
  • 然后一个一个去观察,查找可能内存泄露的地方,(看生命周期是否一致/读代码,可以通过快照对比)如果生命周期一致,则无泄露
    在这里插入图片描述

二、MAT

性能优化02_MAT使用

三、设置监听导致的内存泄漏

1 Demo

MyView

public class MyView extends View {
    public MyView(Context context) {
        super(context);
        init();
    }


    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        ListenerCollector collector = new ListenerCollector();
        collector.setListener(this,myListener);
    }

    public interface MyListener {
        void mylistenerCallback();
    }

    private MyListener myListener = new MyListener() {
        @Override
        public void mylistenerCallback() {
            System.out.print("被调用");
        }
    };
}

ListenerCollector

public class ListenerCollector {

    static private WeakHashMap<View, MyView.MyListener> slistener = new WeakHashMap<>();

    public void setListener(View view, MyView.MyListener listener) {
        slistener.put(view, listener);
    }

    public static void clearListeners() {
        //移除所有监听
        slistener.clear();
    }
}

ListenerActivity

public class ListenerActivity extends AppCompatActivity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyView myView = new MyView(this);
        setContentView(myView);
    }

  /*  @Override
    protected void onStop() {
        super.onStop();
        ListenerCollector.clearListeners();
    }*/
}

2 出现泄漏

运行进入这个Activity的页面,横屏后,分析内存,发现Activity泄漏
在这里插入图片描述

3 查找原因

  1. Mat打开转换后的.hprof文件->Histogram视图

  2. 搜索要查找的类如MainActivity(relgex),搜索(Regex -enter键),右键搜索结果,List objects(查看被谁引用和引用了谁),选择with incoming references查看被引用情况
    在这里插入图片描述

  3. 分析技巧:排除容易被回收的(软引用、虚引用、弱引用),右键搜索结果,
    Path To GC Roots - exclude all phantom/weak/soft etc. references
    在这里插入图片描述
    最终我们找到了不能被回收导致Activity泄漏的地方

  4. 解决方法:Activity的onStop清除监听 ListenerCollector.clearListeners();

  5. Demo:ListenerActivity

4 MAT两个.hprof文件进行对比

选中一个.hprof文件,点击Navigation History - 选中histogram-Add to Compare Basket ,再选中另一.hprof文件重复操作;然后右上角compare the results
在这里插入图片描述
找到对应的Activity,看看是否泄漏
在这里插入图片描述

发布了211 篇原创文章 · 获赞 63 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/baopengjian/article/details/103911523
今日推荐