OOM:所申请的内存 > 可分配内存 - 已分配内存
内存抖动:申请的内存过大 -> 创建了大型实例或短时间内创建了非常多的小实例
内存泄漏:实例的生命周期结束后依然存在GCRoot的引用链条上,垃圾回收器依然认为实例有用
内存治理三板斧:回收 压缩 复用
-
堆内存溢出
-
垃圾回收 STW
STW:Stop the world:GC的同时暂停一切用户线程
- 并行、并发回收
- 缩小回收范围
-
内存分配 OOM
解决内存抖动、内存泄露
-
-
线程数超限
线程数超限 OOM 消灭野线程
-
FD泄漏
FD 也叫文件句柄,在 Linux 里,文件、目录、块设备、字符设备、管道等都被抽象成了文件,所以在调用这些文件的时候,都会返回一个 FD。
FD数超限 OOM
FD泄漏原因是FD没有及时释放:文件未正常关闭、I/O未正常关闭、Cursor未正常关闭
治理思路:及时关闭I/O操作、及时关闭数据库和Cursor、及时释放HandlerThread
Bitmap 内存治理:三级缓存
- 能控制内存总占用
- 避免重复创建 Bitmap
- Activity 被静态变量或单例所持有
- 被其他长生命周期实例持有
- 注意:尽量别作为参数传递Activity
- 注意:Activity 生命周期结束时取消异步任务
OOM:pthread_create failed.
- 系统分配线程栈失败
- 系统内存不足的时候启动线程
- 进程内运行的线程数超过了系统的限制,需要控制并发线程数来解决
- 使用线程池或 Kotlin 协程
- 谨慎使用static、顶层变量和单例
- 关注内部类的生命周期
- 注册与反注册要成对出现
- 需要context的情况尽量使用Application Context
- 酌情使用枚举
- 尽量避免自动拆装箱
- 避免过度的页面绘制
- 及时关闭I/O和Cursor
- 及时释放HandlerThread
- Android Profiler:Android Studio 内置的 Profiler 工具可以用于监控内存使用情况,但它主要用于开发和测试阶段,而非线上环境。
- LeakCanary:一个开源库,用于检测 Android 应用中的内存泄漏。它可以在开发过程中使用,也可以配置为在线上环境中运行,以便捕获并报告内存泄漏。
- MAT (Memory Analyzer Tool):一个强大的 Java 堆分析工具,用于分析大型堆转储。它可以帮助你找到内存泄漏和减少内存占用。
-
存储内容
堆内存:主要用于存储 Java 程序中创建的对象。
栈内存:存储基本类型的变量(如 int、float 等)和对象引用变量的实际值,这些变量通常是方法的局部变量和方法调用的参数。
-
内存管理
堆内存:由 Java 垃圾回收器管理。
栈内存:遵循后进先出(LIFO)的原则进行内存管理。当方法结束时,方法中的所有栈帧都会自动释放。
-
生命周期
堆内存:生命周期较长,它随着应用程序的运行而存在。
栈内存:生命周期较短,只在单个方法调用中存在。
-
线程安全
堆内存:由于可能被多个线程共享,因此访问堆内存通常涉及到线程安全性问题。
栈内存:每个线程都有自己的栈内存,因此从线程安全的角度来看,栈内存是安全的。
-
内存空间大小
堆内存:通常有较大的空间,可以动态扩展。
栈内存:相对较小,有严格的物理限制。