Android内存泄漏8种可能及完善解决方案

本文探讨了Android应用中常见的两种内存泄漏类型:传统内存泄漏和逻辑内存泄漏,并重点讲解了由于静态Activity、内部类(如AsyncTask、Handler、Runnable等)、Sensor Manager未正确释放引起的内存泄漏问题。提供了解决这些问题的策略,包括使用弱引用和及时移除回调等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

借鉴自https://www.jianshu.com/p/ac00e370f83d


一般内存泄漏(traditional memory leak)的原因是:由忘记释放分配的内存导致的。(Cursor忘记关闭等)
逻辑内存泄漏(logical memory leak)的原因是:当应用不再需要这个对象,当仍未释放该对象的所有引用。


如果持有对象的引用,垃圾回收器是无法回收这个对象的。但是并不是说,引用被别人持有了,就是内存泄漏了。比如activity,你在用,那就不叫内存的泄漏,内存该花还是得花。但是当用户跳转到别的activity了,销毁了之前的activity,这个时候,如果之前那个activity的资源还没有被释放这就说不过去了。最典型的原因是之前的activity的实例依然被另外的对象持有着。有些显示的引用还好说,隐式的如内部类的引用,可就真的难以查出来了。


最典型的,静态activity

private Activity activity = null;
public void setActivity(Activity activity) {
    this.activity = activity;
}
这个类一旦被加载了,那么好了,从现在开始,到整个应用结束,这个activity的实例一直就被维护在这里了。怎么解决?你得注意在Activity的onDestory里释放他啊。此外,不仅仅是静态的activity,静态的占大内存的资源比如View,也有内存大面积泄漏的危险,也需要进行一个释放。

(维护成弱引用也行,如private static WeakReference<MainActivity> activityReference)


内部类(async task、handler、runnable、thread、timer task等等,只要是非静态内部类+可能延时的都会啊)

不管是匿名的还是非静态的内部类,都会持有外部类的强引用。如果你这个内部类是handler,runnable等,就危险了,因为message的target会持有handler的引用,message的callback会持有runnable的引用,而runnable、handler又会隐式持有activity的实例,所以这一串链式调用上的所有实例都不会被释放,boom。还有正常的内部类(不延时的)也会出现问题,当你把这个内部类声明成静态成员变量的时候。这个时候静态的是不会被销毁的,所以内部类不会被销毁,而内部类会隐式持有activity的实例,这个时候也内存泄漏了。

(解决方式请看:Android Handler、非静态、匿名内部类的内存泄漏,用静态内部类+弱引用或handler.removeCallbackAndMessages(null)http://blog.youkuaiyun.com/qq_36523667/article/details/78945778)


Sensor Manager

通过Context.getSystemService(int name)可以获取系统服务。这些服务工作在各自的进程中,帮助应用处理后台任务,处理硬件交互。如果需要使用这些服务,可以注册监听器,这会导致服务持有了Context的引用,如果在Activity销毁的时候没有注销这些监听器,会导致内存泄漏。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值