2021-05-27

内存优化

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

猜你喜欢

转载自blog.csdn.net/DikY_/article/details/117336270