总结所有导致内存泄露的可能性及解决方案
1。 非静态内部类或匿名内部类的静态实例
非静态内部类或匿名内部类会持有外部类实例的引用,如果非静态内部类的实例是静态的,就会间接的长期维持着外部类的引用,阻止被系统回收。
private static class MessageHandler extends Handler {
private final WeakReference<MainMessageF> contextWeakReference;
public MessageHandler(MainMessageF context) {
contextWeakReference = new WeakReference<MainMessageF>(context);
}
@Override
public void handleMessage(Message msg) {
if (contextWeakReference.get() != null) {
switch (msg.what) {
case 0:
removeMessages(0);
BleUtils.sendBrake(new byte[]{0x01, 0x04, 0x00, 0x02, 0x00, 0x07});
sendEmptyMessageDelayed(0, 2000);
break;
case 1:
removeMessages(1);
removeMessages(0);
BleUtils.sendBrake(new byte[]{0x01, 0x03, 0x00, 0x00, 0x00, 0x01});
sendEmptyMessageDelayed(0, 500);
break;
}
}
}
}
private MessageHandler mHandler = new MessageHandler(this);
2. 未正确使用Context
对于不是必须使用Activity Context的情况(Dialog的Context就必须是Activity Context),我们可以考虑使用Application Context来代替Activity的Context,这样可以避免Activity泄露。
3. 静态View
使用静态View可以避免每次启动Activity都去读取并渲染View,但是静态View会持有Activity的引用,导致Activity无法被回收,解决的办法就是在onDestory方法中将静态View置为null。
4. WebView
不同的Android版本的WebView会有差异,加上不同厂商的定制ROM的WebView的差异,这就导致WebView存在着很大的兼容性问题。WebView都会存在内存泄漏的问题,在应用中只要使用一次WebView,内存就不会被释放掉。通常的解决办法就是为WebView单开一个进程,使用AIDL与应用的主进程进行通信。WebView进程可以根据业务需求,在合适的时机进行销毁。
5. 资源对象未关闭
资源对象比如Cursor、File等,往往都用了缓冲,不使用的时候应该关闭它们。把他们的引用置为null,而不关闭它们,往往会造成内存泄漏。因此,在资源对象不使用时,一定要确保它已经关闭,通常在finally语句中关闭,防止出现异常时,资源未被释放的问题。
6. 集合中对象没清理
通常把一些对象的引用加入到了集合中,当不需要该对象时,如果没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就会更加严重。
7. Bitmap对象
临时创建的某个相对比较大的bitmap对象,在经过变换得到新的bitmap对象之后,应该尽快回收原始的bitmap,这样能够更快释放原始bitmap所占用的空间。
避免静态变量持有比较大的bitmap对象或者其他大的数据对象,如果已经持有,要尽快置空该静态变量。
8. 监听器未关闭
很多系统服务(比如TelephonyMannager、SensorManager)需要register和unregister监听器,我们需要确保在合适的时候及时unregister那些监听器。自己手动add的Listener,要记得在合适的时候及时remove这个Listener。
9. Static Actitivities
构造静态变量持有Activity
对象很容易造成内存泄漏,因为静态变量是全局存在的,所以当MainActivity
生命周期结束时,引用仍被持有。这种写法开发者是有理由来使用的,所以我们需要正确的释放引用让垃圾回收机制在它被销毁的同时将其回收。