Bootstrap

用Android Studio进行内存分析调试

运用Android Studio对程序进行内存分析和调试

一、界面介绍
打开Android Studio看下它的界面,在最底下可以找到 Android Monitor标签,点击打开它,如下图所示。
在这里插入图片描述
第一个Memory就是用来监测当前程序的内存使用状态的,我们只看这个。有的人打开后可能只能看到Logcat模块,不要急,在logcat的最右边找找,看有没有一个小图标,有就点开它,立马就会出现Monitors模块。

看看下面这个部分:
在这里插入图片描述
代表监视器目前监测的手机。
在这里插入图片描述
这里用来显示监视器正在监测的进程,点击右边的下拉箭头,可以选中某一个进程进行监视。

有的人会出现这种现象,打开monitor模块,发现所有的monitor全部disable,这样你可以查看下刚刚提到的两个部分是否是[DISCONNECT]和[DEAD]的:

在这里插入图片描述
如果是的话,就去点右边的下拉箭头,选中一个正常的设备和进程就行了。如果还解决不了,那么参考这篇文章http://blog.csdn.net/yangxi_pekin/article/details/51860998不过我用的是模拟器,重启下就好了。

还要提一下,如果你发现CPU和Network monitor能够正常工作,但Memory和GPU monitor is disabled,那么尝试着点击旁边的暂停按钮,多点几次就好了

在这里插入图片描述
相关链接:http://stackoverflow.com/questions/38202637/memory-monitor-is-disabled-in-android-studio

二、Memory 界面
在这里插入图片描述
五个按钮的作用从左到有分别是:

  1. (Enabled)暂停内存监视器的工作
  2. (Initial GC)启动垃圾回收,一般在Dump Java Heap之前用来清楚无用对象。
  3. (Dump Java Heap)生成一份当前内存使用情况的日志
  4. (Start Allocation Tracking)记录一段区间内各个线程各个方法的内存分配情况
  5. (Memory monitor help)查看帮助文档

说明一下Start Allocation Tracking,先点击它启动这个功能,然后在手机上做一些操作,然后再点一次就会结束此次内存的记录。最后你会发现AS自动生成了alloc文件。
在这里插入图片描述
图中记录了四个线程在我操作手机时在内存分配的堆空间。

三、内存调试
现在用代码模拟一个内存泄漏程序:

package com.phoenix.l_ui;

import android.app.Activity;

import java.util.LinkedList;
import java.util.List;

/**
 * Created by developer on 16-10-21.
 */

public class Cache {
    private static Cache cache = null;

    private List<Activity> activityList = new LinkedList<Activity>();

    public static Cache getInstance() {
        if (cache == null) {
            synchronized (Cache.class) {
                if (cache == null) {
                    cache = new Cache();
                }
            }
        }
        return cache;
    }

    public void addAty(Activity aty) {
        activityList.add(aty);
    }

}

新建一个单例子类,里面的activityList用于存储程序的MainActivity

package com.phoenix.l_ui;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    Object[] objs = new Object[1000]; //使得内存泄漏更明显

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Cache.getInstance().addAty(MainActivity.this);
    }
}

不停的旋转手机屏幕,MainActivity本应该不停的销毁重建,但是每次创建MainActivity时,cache就会自动将MainActivity加入引用,所以MainActivity是不会销毁的,这样在程序里面就会存在多个activity实例造成内存泄漏。

在这里插入图片描述
看旁边的英文提示,可以知道内存使用量是在增加的,虽然有下降,单总体来说是上升的,我们可以猜测发生了内存泄漏,所以我们需要把生成一份当前内存的日志文件。

启动init GC,然后再Dump Java Heap,AS会自动生成.hprof文件,如下图显示:
在这里插入图片描述
把上图显示的 Class List VIew切换到 Package Tree View,进入应用的包名中,可以看到MainActivity的实例有41个:
在这里插入图片描述
这就是Memory的基本用法,不过一般情况下我们是不知道到底是什么地方发生了内存泄漏,所以需要dump Java heap次内存日志,对比日志之间的差异,看是什么地方的对象引用数量增加的比较多,这样就可以分析出哪里需要优化。

;