Android APP常见的5类内存泄露及解决方法

时间:2023-03-09 01:40:53
Android APP常见的5类内存泄露及解决方法

1.static变量引起的内存泄漏 
因为static变量的生命周期是在类加载时开始 类卸载时结束,也就是说static变量是在程序进程死亡时才释放,如果在static变量中 引用了Activity 那么 这个Activity由于被引用,便会随static变量的生命周期一样,一直无法被释放,造成内存泄漏。

解决办法: 
在Activity被静态变量引用时,使用 getApplicationContext 因为Application生命周期从程序开始到结束,和static变量的一样。注意有些场景不能使用Application的Context 代替Activity的Context,比如传入Context构建静态的ProgressDialog对象,ProgressDialog要依附父View而存在,Application的Context 中没有View,这是只能继续使用Activity的Context;解决方法,可以换成在改Activity的OnDestroy方法执行时,将静态的ProgressDialog对象设为null。这样它不再拥有Activity的引用,Activity可以被及时回收。

2.线程造成的内存泄漏 
类似于上述例子中的情况,线程执行时间很长,及时Activity跳出还会执行,因为线程或者Runnable是Acticvity内部类,因此握有Activity的实例(因为创建内部类必须依靠外部类),因此造成Activity无法释放。 
AsyncTask 有线程池,问题更严重

解决办法: 
1.合理安排线程执行的时间,控制线程在Activity结束前结束。 
2.将内部类改为静态内部类,并使用弱引用WeakReference来保存Activity实例 因为弱引用 只要GC发现了 就会回收它 ,因此可尽快回收

3.BitMap占用过多内存 
bitmap的解析需要占用内存,但是内存只提供8M的空间给BitMap,如果图片过多,并且没有及时 recycle bitmap 那么就会造成内存溢出。

解决办法: 
及时recycle 压缩图片之后加载图片

4.资源未被及时关闭造成的内存泄漏 
比如一些Cursor 没有及时close 会保存有Activity的引用,导致内存泄漏

解决办法: 
在onDestory方法中及时 close即可

5.Handler的使用造成的内存泄漏 
由于在Handler的使用中,handler会发送message对象到 MessageQueue中 然后 Looper会轮询MessageQueue 然后取出Message执行,但是如果一个Message长时间没被取出执行(比如执行了Handler的postDelayed()方法),那么由于 Message中有 Handler的引用,而 Handler 一般来说也是内部类对象,Message引用 Handler ,Handler引用 Activity 这样 使得 Activity无法回收。

解决办法: 
依旧使用 静态内部类+弱引用的方式 可解决

其中还有一些关于 集合对象没移除,注册的对象没反注册,代码压力的问题也可能产生内存泄漏,但是使用上述的几种解决办法一般都是可以解决的。