内存优化基础
内存优化基础
内存优化基础
物理内存和虚拟内存
现代操作系统都不直接操作物理内存,而是虚拟内存。App 申请的内存也都是虚拟内存。
对于每个 app 来说,在 32 位操作系统,都认为自己的进程独享 2^32 容量的虚拟内存,实际上占用多少物理内存,用的时候再去分配,64 位系统是 2^48,而不是 2^64,因为 256TB 足够大了,用 2^64 会有大量寻址空间浪费。
虚拟内存分为用户空间和内核空间,对于 32 位系统,内核空间所有进程共享,大小 1GB,用户空间不共享,大小 3GB
Android 内存分配策略
- 静态分配,使用方法区,存储已被虚拟机加载的类信息、常量、静态变量等;在程序编译时就已分配好,存在于程序整个运行期间(不需要回收的)
- 栈式分配,使用栈区,方法执行时以栈帧的形式存储局部变量、数据类型和对象的引用等;方法结束后栈帧自动释放内存
- 堆式分配,使用堆区,存储 Java 对象实例;由 GC 自动管理内存回收
内存释放策略
其实就是垃圾回收算法。
- 标记清除,先标记后清除,会产生大量不连续的内存碎片,效率低,一般用于老年代
- 复制,内存一分为二,适用于新生代
- 标记 - 整理,老年代
- 分代收集,现在虚拟机基本都采用这种,新生代采用复制算法,老年代采用标记清除/标记 - 整理算法
内存数据的获取
内存指标
#
内存优化方法论
- Java 堆(Java Heap)内存优化
- Native 内存优化
- 虚拟内存优化
Java 堆优化
Java 内存优化的 3 条方法论:
- 减少加载进程 Java 堆的数据
- 及时清理加载进 Java 堆的数据
- 增加 Java 堆空间可用大小
减少加载进 Java 堆的数据
减少缓存大小
缓存是通过空间换时间的方式提升业务体验。
以 LruCache 为例,一般说缓存 size 设置为最大可用堆的 1/8,这样设置其实不太准确,需要评估业务的重要性和业务使用频率
- 使用频率高的 size 多设置一点
- 评估机型,堆空间的大的 512M,size 设置为 1/8;低端机设置为 1/9 等
- 及时清理缓存,超过 Java 内存 80% 就清理 LruCahe 的数据
按需加载数据
真正用到的时候再去加载数据
转移数据
Java 堆大小有限制,主流只有 512M,转移数据的方式有 2 种:
- 将 Java 堆的数据转移到 native
- 将当前进程中 Java 堆的数据转移到其他进程中:如 WebView,小程序等。
及时清理加载进 Java 堆的数据
增加 Java 堆的大小
Native 内存优化
https://swe84nm8d7.feishu.cn/wiki/wikcnXi38oIwe03FmPULuNs24ef
虚拟内存优化
1. 线程池 - 线程收敛
每个线程,空的都要占用 1M 的虚拟内存空间
2. hook 将 1M 的空间改为 512K
繁重的线程不修改
其他
Bitmap 相关
- 使用 Bitmap 解码格式 AGRB_888、ARGB_565、ARGB_4444、ALPHA_8
代码质量 - 用 shape 替代图片
- RecyclerView item 复用
- 使用对象池
- 使用线程池
- 谨慎使用帧动画
- onTrimMemory() 释放资源
大图优化?
通过 Flipper 等工具查看应用中的大图
代码优化
HashMap 替代品
- ArrayMap 替换 HashMap;底层是 array,少创建 HashMapEntity,还是存在自动装拆箱问题
- SparseArray 替换 HashMap;底层是 int array,可避免装箱问题
- 1000 以内,key 为 int 的用 SparseArray,key 不是 int 的用 ArrayMap
Ref
「抄底 Android 内存优化 8」 —— 快手线上 OOM 监控学习笔记
内存优化 · 方案篇 · 安卓native内存分析
内存优化相关问题?
线上做内存泄漏检测有什么思路吗?
线上内存怎么监控?
什么时候 dump 内存?如何 dump 内存?dump 下来怎么裁剪、上传、分析?
KOOM、LeakCanary 和 Matrix 方案?
- LeakCanary 和 Matrix 由于 dump 的整个过程会影响到主进程,所以基本应用与线下监控
- KOOM 提出了 fork dump 的概念,能在 dump 分析内存泄漏的时候而不影响主进程的应用运行,适合线上监控
有什么实际解决 UI 卡顿优化的经历
有做过什么 Bitmap 优化的实际经验
mainfest 中配置 LargeHeap,真的能分配到大内存吗?
当 largeHeap=true 时:结论就是,设置 largeHeap 的确可以增加内存的申请量。但不是系统有多少内存就可以申请多少,而是由 dalvik.vm.heapsize
限制
本文由作者按照 CC BY 4.0 进行授权