Android内存优化之内存泄漏

内存泄漏

内存泄漏一般有以下几种情况:单例、静态变量、Handler、匿名内部类、资源使用未关闭

单例导致的内存泄漏

单例的情况主要是因为单例的生命周期比较长,如果引用的一些资源(比如Context、图片等)没有做特殊处理,就容易导致内存泄漏。具体的分析可以查看文章:Android 单例模式的正确姿势

静态变量导致的内存泄漏

静态变量的生命周期同样很长,如果引用了一些资源没有及时释放的话就会导致内存泄漏,比如Context、图片的引用等。

引用图片资源,这样写就要小心了。

private static LinkedHashMap mapPool;

引用的是Context,比如Activity。

public class MyActivity extends AppCompatActivity {

    private static MyClass myClass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (myClass == null) {
            myClass = new MyClass(this);
        }
    }

    class MyClass {
        MyClass(Activity activity) {

        }
    }
}

Activity退出后myClass仍然持有Activity的引用导致Activity无法被回收。

Handler导致的内存泄漏

Handler导致的内存泄漏需要先充分理解Android的消息机制,其中跟内存泄漏有关的一个点就是消息Message会持有Handler引用,这样的话如果消息队列中有消息还没有处理完的话,Handler就无法释放,这个时候如果Handler里面还引用了Activity或是其他资源,那就会导致内存泄漏。

一种情况是Handler是内部类,由于内部类会默认引用外部类,这时候如果外部是Activity等,就可能造成内存泄漏

public class MainActivity extends AppCompatActivity {

    private static LinkedHashMap mapPool;
    
    private class MyHandler extends Handler {
        @Override
        public void handleMessage(Message message) {
            
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
    }
     
}

解决方式也简单,就是将Handler定义为静态内部类。当然如果Handler里面还显示引用了Context或是View等资源,最好用弱引用。

匿名内部类

匿名内部类导致的内存泄漏原因是匿名内部类会默认引用外部类,如果外部类是Activity等资源型类的话就会导致内存泄漏。所以你看我们通过自动工具生成的一些类,比如我们用GsonFormat生成的实体Bean,内部类都是静态的。

资源使用未关闭

资源使用未关闭这个比较好理解,常见的资源类型有广播BraodcastReceiver、ContentObserver、File、数据库游标Cursor、以及Stream和Bitmap。在使用这些资源时我们就需要注意在不使用的时候需要及时释放这些资源。

系统bug导致的内存泄漏

这种情况不用检测工具很难发现,比如LeakCanary。这里就记录一个InputMethodManager导致的内存泄漏。具体情形和解决方法可以查看文章:Android InputMethodManager内存泄漏 解决方法总结

感谢尘封的落叶的提醒。


                    欢迎关注我的微信公众号,和我一起每天进步一点点!
Android内存优化之内存泄漏_第1张图片
AntDream

你可能感兴趣的:(Android内存优化之内存泄漏)