Android(java)内存泄露(Memory Leak)

Android中内存泄露分类

一、context使用不当导致的内存泄露

根本原因在于,context(比如Activity)是有生命周期的,它被一个更长生命周期的对象所持有,导致了内存泄露。具体分为:

(1)静态context导致的泄露,因为静态变量的生命周期和类是一致的,类只要加载进来就一直在,静态变量保存在方法区的;

         一个静态变量,间接引用了context,比如已经让view展示的静态Drawable(我觉得一个成熟的开发者没有这样干的);

(2)单例对象中有变量引用了context导致的泄露

(3)非静态内部类(包括匿名内部类)隐式引用context导致的泄露

        a、线程引用外部类对象

        b、Handler导致内存泄露问题

              Android Handler内存泄露

              Android App 内存泄露之Handler

Handler采用静态内部类+WeakReference的方式,Activity退出后,等到GC的时候,弱引用的Activity就会被回收掉,但是那些在Activity中通过Handler放到消息队列中的消息还在(如果还没到时间处理),Activity都退出了,这些消息是没有意义了,这种还是有“一些”泄露,因为消息最终肯定会被执行的,我把这种泄露叫“泄露了一段时间”。

所以最好的做法是在Activity的onDestroy的方法中,remove掉所有消息。

特殊说明:Handler使用过程中,内部类默认引用外部类对象导致的泄露,还具体分为两种,一种是内部类handler,另一种是handler发送的Runnable内部类。具体逻辑,大家可以自行思路。

参考:

避免Android中Context引起的内存泄露

Android 如何避免 Context 内存泄露

二、

ThreadLocal用法详解和原理(weakReferenc 和 内存泄露)

Handler导致的内存泄露,我们通过静态内部类和弱引用的方式解决,虽然可能会导致“泄漏一段时间”,但最终还是能保证没有内存泄漏。可是ThreadLocal,官方虽然把key采用弱引用的方式,防止内存泄漏,但是也不能保证百分百的不内存泄漏,原因请看上面的文章,所以最好的办法还是ThreaLocal不用的时候,先remove一下,先把当前线程ThreaLocalMap中存的key value先移除,然后把ThreadLocal的引用置为null,这样ThreadLocal就不会导致内存泄漏了。不过官方建议ThreadLocal 设置成static的,这样也没有释放的必要,也不会有内存泄漏,比如Android Looper中ThreadLocal的使用。

三、使用线程的时候很容易导致内存泄漏,如使用Thread或者AsyncTask,这个网上有很多的说明。如果规范使用线程,可以看看《阿里巴巴Android使用规范》Android(Java)线程使用规范

四、在缓存对象的时候,也可能会导致内存泄漏Glide之ActiveResource

发布了189 篇原创文章 · 获赞 25 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/lizhongyisailang/article/details/104135059