urlname
type
Post
password
SyncToConfluence
category
学习笔记
date
Feb 22, 2023 14:09
slug
eb4a1ce4c92c
icon
Button
catalog
summary
tags
Android
性能优化
cover
Status
BusyTime
Status 1
status
Published

内存优化的三部曲

  • Java Heap 优化
  • Native 优化
  • 虚拟内存 优化

Java Heap 组成

当 Android 虚拟机启动时,便会创建 Java 堆,后续所有 Java 对象所需要的内存都会从这个堆中分配
由不同的 Space 组成,且所有 Space 的创建,都是先通过 mmap 申请一块匿名内存,然后将这块内存放入对应的 Space 空间中进行管理
而划分不同 Space 的原因,主要是:每个 Space 存放对象的性质都不一样,比如系统对象的存活周期非常长,而有些应用对象的存活周期非常短,并且不同的 GC 算法对空间的要求也不一样,标记清楚只需要一个空间,但是复制回收就需要两个空间,不同的 Space 对内存的申请和释放都不一样,适用的场景也不一样
  • ImageSpace
  • ZygoteSpace
  • Non moving space
  • LargeObjectSpace
  • MainSpace

ImageSpace

用来存放 系统库 的对象,大小不固定。

ZygoteSpace

存放 Zygote 进程在启动过程中 预加载和创建 的各种对象,应用进程为 2M 左右,Zygote 进程为 64M,挨着 Image Space。

Non moving space

如果非 zygote 或 Native 进程启动时(即应用进程,其 ZygoteSpace 为 2M),便会将 ZygoteSpace 切分出 62M 左右,当做 non moving space,用来存放一些 生命周期较长 的对象。

LargeObjectSpace

用来存放 大对象,大对象是大于 12K 的 基本类型数组 和 String 对象。

MainSpace

大对象以外的大部分的 Java 对象都会存放在这块空间。
notion image
  • 值得注意的是,虽然 MainSpaceLarge Object Space 都分配了 512M 的虚拟内存,但512M 只是这两个空间理论上可申请的最大内存,而在真正申请内存时,虚拟机会用 num_bytes_allocated_ 这个标志位来记录已经分配的内存,不管是在 MainSpace 还是 Large Object Space 中分配的空间,都会通过这个标志位累加记录下,如果这个值超过了阈值(标志位为 growth_limit_),就会抛出 OOM

Java 对象的申请与释放

申请对象的两种方式

在 Java Heap 中申请内存时,如果申请失败,或者申请完毕后超过了阈值,就会执行 GC,然后重新申请,如果还是内存不足,就 OOM
  • 显示加载
    • 使用 Class.forName() 或者 ClassLoader.loadClass() 方式加载对象。
  • 隐式加载
    • 使用 new,反射 或者访问静态变量或者函数加载对象。

对象释放流程

对于 ART 虚拟机的垃圾回收器来说,是通过可达性分析来判断一个对象是否可以被回收。
  • 选择合适的 GarbageCollector(垃圾回收器),并设置好这个 collector 的环境,如 kCollectorTypeSS(半空间回收)就会设置好 FromSpaceToSpace
  • 接着调用执行 collector->Run 接口,collector 会执行对象的回收策略

优化方案

优化的目的是,让 Jave Heap 中保持尽量充足的空间,主要的三种思路,一个是 减少来源,一个是 促进回收,一个是 增大储蓄
  • 三种基本方法论:
    • 减少加载进程 Java 堆的数据
    • 及时清理加载进 Java 堆的数据
    • 增加 Java 堆空间可用大小

减少加载进 Java 堆的数据

  • 减少堆里的数据,可以从以下几个角度出发:
    • 减少缓存大小
    • 按需加载数据
    • 转移数据

转移数据

  • 将 Java 堆的数据转移到 Native 中。
    • Bitmap
  • 将当前进程中 Java 堆的数据转移到其他进程中。

及时清理加载进 Java 堆的数据

如在业务结束和内存不足时,主动销毁已经不需要的对象

增加 Java 堆空间可用大小

通过 Hook ART 虚拟机技术,来修改分配给 Java Heap 的空间大小
Leetcode_78-子集App的内存模型
Loading...