内存泄露和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加载导致内存泄漏一般怎么优化
Bitmap对象不在使用时调用recycle()释放内存
图片压缩后再加载
软引用缓存bitmap对象
用框架
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 协议 ,转载请注明出处!