内存优化
1.内存泄露
程序在申请内存后,当该内存不需再使用但却无法被释放 & 归还给程序的现象,对应用程序的影响
容易使得应用程序发生内存溢出,即 OOM
2.集合类
集合类添加元素后,仍引用着 集合元素对象,导致该集合元素对象不可被回收,从而 导致内存泄漏
解决方案:集合类添加集合元素对象后,在使用后必须从集合中删除
3.Static关键字修饰的成员变量被 Static 关键字修饰的成员变量的生命周期 = 应用程序的生命周期
泄露原因:
若使被 Static 关键字修饰的成员变量 引用耗费资源过多的实例(如Context),则容易出现该成员变量的生命周期 > 引用实例生命周期的情况,当引用实例需结束生命周期销毁时,会因静态变量的持有而无法被回收,从而出现内存泄露
单例使用导致内存泄漏:若1个对象已不需再使用而单例对象还持有该对象的引用,那么该对象将不能被正常回收从而 导致内存泄漏
解决方案:
1.尽量避免 Static 成员变量引用资源耗费过多的实例,如:Context,如何要使用尽量用Application的context。
2.使用弱引用修饰变量。
非静态内部类 / 匿名类
非静态内部类 / 匿名类 默认持有外部类的引用;而静态内部类则不会
泄漏原因:非静态内部类所创建的实例 = 静态(其生命周期 = 应用的生命周期),会因 非静态内部类默认持有外部类的引用 而导致外部类无法释放,最终 造成内存泄露
常见的场景:AsyncTask、实现Runnable接口、继承Thread类
解决方案:
将非静态内部类设置为:静态内部类(静态内部类默认不持有外部类的引用)
2.该内部类抽取出来封装成一个单例
3.尽量 避免 非静态内部类所创建的实例 = 静态
资源对象使用后未关闭
对于资源的使用(如 广播BraodcastReceiver、文件流File、数据库游标Cursor、图片资源Bitmap等),若在Activity销毁时无及时关闭 / 注销这些资源,则这些资源将不会被回收,从而造成内存泄漏
解决方案:在Activity销毁时 及时关闭 / 注销资源
Handler引起的内存泄漏
静态的内部类结合弱引用。
内存抖动
在一定时间内,大量的创建释放对象,出现的内存波动。
解决方案:通过常用的数据结构,把对应的数据对象做缓存和重复使用。
图片Bitmap相关
使用完毕后若不释放图片资源,容易造成内存泄露,从而导致内存溢出
优化方案:
使用完以后释放图片资源
根据分辨率适配缩放图片
根据需求选择适当的解码方式
图片缓存(三级)
内存优化的辅助工具
MAT(Memory Analysis Tools)
Heap Viewer
Allocation Tracker
Android Studio 的 Memory Monitor
LeakCanary