内存泄露和OOM

内存泄露检测工具

MAT

Java堆分析器,可帮助您查找内存泄漏并减少内存消耗。使用Memory Analyzer分析具有数亿个对象的高效堆转储,快速计算对象的保留大小,查看谁阻止垃圾收集器收集对象,运行报告以自动提取泄漏嫌疑者。

LeakCanary

什么是内存泄露

就是系统回收不了分配出去了不使用的对象。

内存泄露的分类

常发性内存泄露

内存泄露的场景

1.单例构造时传入的Context参数类型为Activity

activity退出的时候,单例的生命周期为应用程序的生命周期,activity得不到释放。

正确的做法:用Application的Context

2.Handler 延迟的消息

延迟的消息Message持有Handler引用,handler为非静态内部类,持有外部activity类的引用,即持有activity的引用。

还应该在Activity的Stop 或者Destroy中移除消息队列的消息。

3.匿名内部类持有外部类的引用,若是这个引用传入到一个异步线程

而该线程的生命周期和activity不一致,也就造成了activity的泄露。

怎样避免内存泄露?

1.处理占用内存大并且生命周期较长的对象的时候,尽量使用软引用或弱引用。

eg:保存Bitmap的软引用到HashMap

如果只是想避免OOM,使用软引用,如果对于性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。

2.远离非静态内部类和匿名类,多用private static class

3.集合对象在activity退出时,clear集合,置为null

4.Bitmap对象不在使用时调用recycle()释放内存

5.Context使用不当造成内存泄露

不要对一个activity Context保持生命周期的引用。尽量在一切可以使用ApplicationContext代替Context的地方进行替换

6.退出acitivty时切记结束线程

handlerThread的run是一个死循环,要在activity销毁中调用handlerTHread.getLooper().quit()

7.对象的注册与反注册没有成对出现

譬如注册广播接收器,

8.创建与关闭没有成对出现,比如Cursor资源必须手动关闭

BITMAP加载导致内存泄漏一般怎么优化

  1. Bitmap对象不在使用时调用recycle()释放内存

  2. 图片压缩后再加载

  3. 软引用缓存bitmap对象

  4. 用框架

ActivityManager activityManager = (ActivityManager) this.getActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
int memClass = activityManager.getMemoryClass();
Log.d(TAG, "onCreate: memClass > " + memClass);
9.0 华为 ANE_AL00 384mb
8.1.0 一加 A5010 256mb
8.1.0 坚果pro2s 256mb
131mb

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!