一、内存管理机制:垃圾回收(GC)是核心
-
Dalvik vs ART 虚拟机
- Android 5.0 前用 Dalvik,之后用 ART。
- ART 优化了 GC 算法,支持内存整理(减少碎片),性能更好。
-
分代模型(Generational Heap)
- 年轻代:新对象在此分配,GC 频繁(用复制算法)。
- 老年代:存活久的对象,GC 较少(用标记-整理算法)。
- 持久代(已淘汰):存放类信息,现被元空间(Meta-space)替代。
-
GC 触发场景
- 分配内存不足时(
kGcCauseForAlloc),导致卡顿(Stop-the-world)。 - 后台内存不足时(
kGcCauseBackground),不影响前台流畅度。
- 分配内存不足时(
二、优化内存的意义
- 减少 OOM:防止应用崩溃。
- 减少卡顿:频繁 GC 会导致界面卡顿。
- 提升存活率:后台应用更不易被系统杀死。
- 避免逻辑隐患:如内存泄漏导致功能异常。
三、内存泄漏:隐形杀手
-
什么是内存泄漏?
- 对象不再使用,但被 GC Roots(如静态变量、线程、JNI 引用)强引用,无法被回收。
-
检测工具
- MAT:分析内存快照(HPROF 文件),找出大对象和引用链。
- LeakCanary:自动检测 Activity/Fragment 泄漏,快速定位问题。
-
常见泄漏场景
- 未关闭资源:数据库、文件流、Bitmap。
- 未注销监听:BroadcastReceiver、EventBus。
- 单例/静态变量:持有 Activity 等短生命周期对象。
- 非静态内部类(如 Handler):隐式持有外部类引用。
- WebView:单独进程管理,及时销毁。
-
解决方案
- 使用 弱引用(WeakReference) 或 软引用(SoftReference)。
- Activity 销毁时及时 解绑监听、清空回调、释放资源。
四、优化内存空间
-
减少对象开销
-
避免自动装箱:用基本类型(
int而非Integer)。 -
复用对象:使用对象池(如 Handler 消息复用)、ViewHolder 复用。
-
选择高效数据结构:
ArrayMap/SparseArray(代替HashMap,节省内存)。- 用
IntDef/StringDef替代枚举(减少内存占用)。
-
-
Bitmap 优化
- 压缩尺寸:
inSampleSize按需缩放图片。 - 降低格式:
RGB_565(无透明通道)比ARGB_8888省一半内存。 - 复用内存:
inBitmap重用已回收的 Bitmap 内存区域。 - 及时回收:页面不可见时释放 Bitmap(如 RecyclerView 的
onViewRecycled)。
- 压缩尺寸:
-
LruCache 缓存管理
- 内存缓存:缓存常用对象(如图片),超出上限淘汰最久未使用的。
- 磁盘缓存:用
DiskLruCache持久化存储,减少网络请求。
五、图片管理模块设计
-
三级缓存架构
- 内存缓存(LruCache):快速读取,高频访问数据。
- 磁盘缓存(DiskLruCache):持久化存储,避免重复下载。
- 网络加载:最终兜底,异步下载后更新缓存。
-
推荐第三方库
- Glide:自动处理图片生命周期,支持内存/磁盘缓存。
- Fresco:专为 Android 设计,内存管理极致优化(特别适合低端机)。
- 优势:封装了缓存、线程池、内存复用等复杂逻辑,开发者更专注业务。
六、实战技巧
-
监控与排查
- 用
adb shell dumpsys meminfo查看内存分布。 - Android Studio 的 Memory Profiler:实时观察内存波动,抓取内存快照。
- MAT 对比分析:对比多次内存快照,找出异常增长对象。
- 用
-
代码习惯
- 避免在循环中创建对象:如
onDraw()内避免 new 对象。 - 及时释放 Native 内存:JNI 分配的内存需手动释放。
- 使用静态内部类:防止外部类被意外持有(如 Handler 用静态类+弱引用)。
- 避免在循环中创建对象:如
-
系统级优化
- onTrimMemory():监听内存紧张事件,释放缓存保命。
- 大图分块加载:用
BitmapRegionDecoder加载局部区域(如地图应用)。
总结
内存优化是性能优化的核心,本质是 减少无效内存占用 和 避免资源浪费。
- 工具:MAT、LeakCanary、Memory Profiler 是必备利器。
- 思想:理解 GC 机制,合理管理对象生命周期,善用缓存与复用。
- 实践:从编码习惯(如及时释放资源)到架构设计(如三级缓存),层层把关。
- 终极目标:让应用 更流畅、更稳定、更省电。
1、Android性能优化之内存优化成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所 - 掘金