美文网首页
内存分析MAT Android Studio

内存分析MAT Android Studio

作者: ab64fd4eaee3 | 来源:发表于2017-03-23 15:05 被阅读96次

    http://www.jianshu.com/p/d8e247b1e7b2

    http://yuanyang5917.github.io/memory-analyzer-tool

    https://joyrun.github.io/2016/08/08/AndroidMemoryLeak/

    Histogram (柱状图)

    Shallow heap

    Shallow size就是对象本身占用内存的大小,不包含其引用的对象。

    常规对象(非数组)的Shallow size有其成员变量的数量和类型决定。

    数组的shallow size有数组元素的类型(对象类型、基本类型)和数组长度决定

    Retained Heap

    Retained Heap的概念,它表示如果一个对象被释放掉,那会因为该对象的释放而减少引用进而被释放的所有的对象(包括被递归释放的)所占用的heap大小。

    Dominator (支配者)tree

    outgoing references :表示该对象的出节点(被该对象引用的对象)。

    incoming references :表示该对象的入节点(引用到该对象的对象)。

    GC Root

    GC发现通过任何reference chain(引用链)无法访问某个对象的时候,该对象即被回收。

    Strong Ref(强引用):通常我们编写的代码都是Strong Ref,于此对应的是强可达性,只有去掉强可达,对象才被回收。

    Soft Ref(软引用):对应软可达性,只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有Strong Ref时才回收对象。一般可用来实现缓存,通过java.lang.ref.SoftReference类实现。

    Weak Ref(弱引用):比Soft Ref更弱,当发现不存在Strong Ref时,立刻回收对象而不必等到内存吃紧的时候。通过java.lang.ref.WeakReference和java.util.WeakHashMap类实现。

    Phantom Ref(虚引用):根本不会在内存中保持任何对象,你只能使用Phantom Ref本身。一般用于在进入finalize()方法后进行特殊的清理过程,通过 java.lang.ref.PhantomReference实现。

    JVM内存区域

    http://www.jianshu.com/p/5db05db4f5ab

    前台进程

    可见进程

    服务进程

    后台进程

    空进程

    https://joyrun.github.io/2016/08/08/AndroidMemoryLeak/

    http://blog.csdn.net/editor1994/article/details/50394560

    第一步:强制GC,生成Java Heap文件

    我们都知道Java有一个非常强大的垃圾回收机制,会帮我回收无引用的对象,这些无引用的对象不在我们内存泄漏分析的范畴,Android Studio有一个Android Monitors帮助我们进行强制GC,获取Java Heap文件。

    强制GC:点击Initate GC(1)按钮,建议点击后等待几秒后再次点击,尝试多次,让GC更加充分。然后点击Dump Java Heap(2)按钮,然后等到一段时间,生成有点慢。

    生成的Java Heap文件会在新建窗口打开。

    第二步:分析内存泄漏的Activity

    点击Analyzer Tasks的Perform Analysis(1)按钮,然后等待几秒十几秒不等,即可找出内存泄漏的Activity(2)。

    那么我们就可以知道内存泄漏的Activity,因为这个例子比较简单,其实在(3)就已经可以看到问题所在,如果比较复杂的问题Android Studio并不够直观,不够MAT方便,如果Android Studio无法解决我们的问题,就建议使用MAT来分析,所以下一步我们就生成标准的hprof文件,通过MAT来找出泄漏的根源。

    第三步:转换成标准的hprof文件

    第四步:MAT打开hprof文件

    右击搜索出来的类名,选择Merge Shortest Paths to GC Roots的exclude all phantom/weak/soft etc. references,来到这一步,就可以看到内存泄漏的原因,我们就需要根据内存泄漏的信息集合我们的代码去分析原因。

    第六步:根据内存泄漏信息和代码分析原因

    使用Handler案例分析,给出的信息是Thread和android.os.Message,这个Thread和Message配合通常是在Handler使用,结合代码,所以我猜测是Handler导致内存泄漏问题,查看代码,直接就在函数中定义了一个final的Handler用来定时任务,在Activity的onDestroy后,这个Handler还在不断地工作,导致Activity无法正常回收。

    // 导致内存泄漏的代码

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_test);

    textView = (TextView) findViewById(R.id.text);

    final Handler handler = new Handler();

    handler.post(new Runnable() {

    @Override

    public void run() {

    textView.setText(String.valueOf(timer++));

    handler.postDelayed(this, 1000);

    }

    });

    }

    修改代码,避免内存泄漏

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_test);

    textView = (TextView) findViewById(R.id.text);

    handler.post(new Runnable() {

    @Override

    public void run() {

    textView.setText(String.valueOf(timer++));

    if (handler != null) {

    handler.postDelayed(this, 1000);

    }

    }

    });

    }

    private Handler handler = new Handler();

    @Override

    protected void onDestroy() {

    super.onDestroy();

    // 避免Handler导致内存泄漏

    handler.removeCallbacksAndMessages(null);

    handler = null;

    }

    相关文章

      网友评论

          本文标题:内存分析MAT Android Studio

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