Android内存泄漏

参考博客1
参考博客2

内存泄漏本质

程序在申请内存后,当该内存不需再使用;但却无法被释放&归还给程序的现象

  • 忘记释放分配的内存
  • 应用不需要某对象时,该对象仍然保持强引用状态

进程优先级

  1. 前台进程(与用户正在交互的进程)
  2. 可见进程
  3. 服务进程
  4. 后台进程
  5. 空进程


当进程空间紧张时,会按进程优先级低到高的顺序自动回收进程

最容易引发内存泄漏

  • Activity
  • Service
  • Application
  • BroadcastReceiver,ContentProvider虽然不在Context继承树,但其内部会持有Context

常见的内存泄漏原因&解决方法

(1)集合类

List objectList = new ArrayList();

for ( int i = 0 ; i < 10 ; i++){

Object o = new Object();

objectList.add(0);

o = null;

}

虽释放了集合元素引用的本身:o = null;

但集合List仍然引用该对象,故垃圾回收器GC,依然不可回收该对象


解决方案:
objectList.clear(); objectList = null;

(2)static关键字修饰的成员变量
使用Application的Context代替Context,使用弱引用
(3)非静态内部类/匿名类
解决方法:
1⃣️将非静态内部类设置为静态内部类
2⃣️将内部类抽取出来封装成一个单例
3⃣️尽量避免非静态内部类所创建的实例 = 静态
(4) 资源对象使用后未关闭


原理:很可能Activity作为Context传递给某些类,Activity生命周期结束后,某些类仍然存活并保持着该Activity的引用,Activity是重量级对象,却保持引用无法被回收

避免内存泄漏的一些方法

  1. 尽量避免使用static变量
  2. 如果逻辑上允许,则使用弱引用(使用WeakReference类实现,可能会有空指针异常)
  3. 继续使用static变量,记得在Activity被销毁的时候,释放static变量引用
  4. 非静态内部类、匿名内部类持有外部类的引用(原理:编译的时候,编译器会自动为内部类构造方法中加上外部类的引用)
  5. Handler内存泄漏问题(使用弱引用)

垃圾回收算法

  1. 标记-清除 算法
  2. 复制 算法
  3. 标记-整理 算法
  4. 分代收集 算法
Author

jiangyao

Posted on

2022-10-19

Updated on

2023-03-08

Licensed under