基于Android Studio的内存泄漏检测与解决全攻略

Posted 优雅的心情

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Android Studio的内存泄漏检测与解决全攻略相关的知识,希望对你有一定的参考价值。

自从Google在2013年发布了Android Studio后,android Studio凭借着自己良好的内存优化,酷炫的UI主题,强大的自动补全提示以及Gradle的编译支持正逐步取代Eclipse,成为主流的Android开发IDE。Android Studio在为我们提供了良好的编码体验的同时,也提供了许多对App性能分析的工具,让开发者可以更方便分析App性能。Google在IO大会上一直告诫开发者不要无节制的使用手机内存,要注意一些不良的开发习惯会导致App的内存泄漏。虽然如今网上检测App内存泄漏的文章汗牛充栋,但是要使用DDMS和MAT,不仅使用步骤复杂繁琐,而且要手动排查内存泄漏的位置,操作起来多有不便。其实Android Studio已经开始支持自动进行内存泄漏检查了,本文就带着大家一探其中的奥妙吧。


什么是内存泄漏
Android虚拟机的垃圾回收采用的是根搜索算法。GC会从根节点(GC Roots)开始对heap进行遍历。到最后,部分没有直接或者间接引用到GC Roots的就是需要回收的垃圾,会被GC回收掉。而内存泄漏出现的原因就是存在了无效的引用,导致本来需要被GC的对象没有被回收掉。


举个栗子

    private static Leak mLeak;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        mLeak = new Leak();
    }

    class Leak {
    }

mLeak是存储在静态区的静态变量,而Leak是内部类,其持有外部类Activity的引用。这样就导致Activity需要被销毁时,由于被mLeak所持有,所以系统不会对其进行GC,这样就造成了内存泄漏。


再举一个最常犯的栗子

public class Singleton {
    private static Singleton instance;
    private Context mContext;
    private Singleton(Context context){
        this.mContext = context;
    }

    public static Singleton getInstance(Context context){
        if (instance == null){
            synchronized (Singleton.class){
                if (instance == null){
                    instance = new Singleton(context);
                }
            }
        }
        return instance;
    }
}

如果我们在在调用Singleton的getInstance()方法时传入了Activity。那么当instance没有释放时,这个Activity会一直存在。因此造成内存泄露。
解决方法可以将new Singleton(context)改为new Singleton(context.getApplicationContext())即可,这样便和传入的Activity没关系了。


内存泄漏的检测
打开Android Studio,编译代码,在模拟器或者真机上运行App,然后点击,在Android Monitor下点击Monitor对应的Tab,进入如下界面