Android开机速度优化简单回顾

学向勤中得,萤窗万卷书。这篇文章主要讲述Android开机速度优化简单回顾相关的知识,希望能为你提供帮助。
android的开机速度, 基本上没人说快的, 通常移植完系统后, 马上要看的事情就是优化开机时间, 以下是简单回忆以下以前做优化的那些事。
开机时间都花在哪?
优化开机时间, 通常做的首先是那有有没有BUG, 明显不合理的先解决, 由于开发阶段稳定性问题, 一些地方可能延时加的大, 或者频率设的低, 先记下来, 后面定期还会再看。这些先不看的话, 一般拿到机器, 我们统计开机时间, 主要看如下几个时间段分布:

  1. 开机按键时间、亮屏时间(基本固定, 除非弄错了, 基本检查一遍确定)
  2. uboot启动时间
  3. 内核启动后到bootanim退出时间
这里我们主要关注的是第三个, 也是优化的重点。这部分时间, 具体都在干啥, 瓶颈是哪, 可以通过bootchart很清楚的看到。以下结合以前抓的图, 简要说一下( 图是很久之前抓的, 比较懒, 没有再跑一遍过程)
Android开机速度优化简单回顾

文章图片


上图中bootanim的退出时间没有截出来, 实际图是有的, 大约是33s的时候结束。
这里分析时, 我们是分了几个时间段:
  1. 内核开始启动, 到init进程开始执行。这个可以通过log看到。
  2. init进程执行, 主要是处理init.rc中的命令, 到core和mainl类服务开始启动的时间, 上图中可以看到, 服务大体都在一个时间点起来的, 约7.5S时, 这之前的一大段空窗期, 也是要重点看的
  3. zygote启动时间
  4. systemserver中各个服务启动时间
  5. 应用启动(systemui/launcher/keyguard..)
以上, 具体分析看每段时间:
第一点另外处理, 具体分析打印看是否有异常, 这个值一般是很小的, 不合理要和BSP同事一起查一下原因。
第二个主要是init.rc执行各种命令, 这个可以通过在execute_one_command函数中统计测量 , 比如大于100ms的命令打印出来, 再分析定位原因, 这里命令执行时间长基本算BUG, 要和BSP工程师一起解决。
第三点主要zygote启动问题, 主要慢的原因, 是加载资源和类库, 这个要读nand, 一般卡的时间比较长, 图中可以看到, zygote进程一溜的小粉红, 说明IO较多。这个preload过程消耗的时间, 在logcat的log中, 也会打印的, 一般来说, 都是在近10S左右。
第四个, zygote初始化完后, 会fork system_server。 system_server进程启动, 耗时也是较长的。根据以前统计分析的结果, 这里的服务启动, 基本上都是花在packageManagerService的PackageScan中, 这又是一个读文件, 卡在文件读取中, 时间长短, 和预制app及安装的app数量有关
第五个时间, 是基本都准备ready后, 启动launcher等应用了, 启动完成后, systemServer请求SurfaceFlinger杀了bootanimation, 就启动完成了。

以上时间中, 主要要优化的, 还是第三步和第四步的IO慢问题, 其他可优化的不多。比如CPU, 常开四核performance模式启动, 也并没提升多少, 一般我们就不管了这个了。

咋优化?
确定优化方向后主要看怎么优化这两段耗时的地方:
1. Zygote的preload 资源和class
2. PackageManagerService的包扫描
这里的第一个, 最早之前有人直接是去掉preload或删减, 虽然可以加快一点开机速度, 但是捡了芝麻丢了西瓜, 根本不能这样干~
我们最早做的实现方式, 是将preload做并行处理, 毕竟现在都是多核处理器了, 而且是preload是加载后还要解析处理的, 并行会有一定幅度提升。
对于包扫描, 这个不好拆成并行任务, 不像preload那么简单干净。考虑过将PackageManager的信息序列化后存起来, 下次开机就不扫了, 不过看起来改动有点大, 不太好搞, 也放弃了。
最后我们的实现的方式, 就是linux上用的较多的readahead机制。具体实现细节就不展开说了, 原理就是:
1. 统计开机过程中, 读取的块数据信息, 记录下来保存
2.再次开机, 通过记录下来的块数据读取信息, 直接起一个服务, 预先开始读, zygote或packagemanagerservice要读文件的时候, 文件数据已经在cache中了。

实际用下来, 这一招特别好, 优化非常明显。以下是实现了一个readahead后的bootchart图:
Android开机速度优化简单回顾

文章图片

可以看到:
1. zygote和system_server都提速了
2. zygote和system_server的IO时间, 都降低非常大
3. 主要IO时间, 跑到readahead进程中去了。


不过, 以上实现, 还是有可优化的地方:
1. readahead进程可以再提前, 在system分区挂载后立刻启动, 这样zygote中的IO应该可以再减小
2. 对system_server的IO, 此时readahead已经结束了, 按理不应该有了, 这里还是有IO, 这一般是后装apk导致, 这个可以把readahead做的更健壮一些, 不要只学习开始的一两次。

其他NB的优化
另外还有一个很NB的技术, 就是STD。这个我们也搞过, 花费了大量的人力物力。STD开机时间, 不算上uboot时间的话, 基本都是在10S内, 5~8S之间。不过这么NB的技术, 目前基本上也是废弃了, 用起来问题也挺多的:
1. 开机时间少了, 关机时间拉长。
由于是STD(Suspend to Disk), 关机时需要将内存数据写入nand, 这块也是挺麻烦的事情

2. 稳定性
本身STD弄起来就比较复杂, BUG挺多的, 另外使用STD, 就相当于永不关机了, 这也太考验系统软件的稳定性了...

3. 没毛用
一开始还能忽悠客户, 不过后来也没人怎么关心这个feature了, 平白给自己找活干, 大家都不乐意使能它了
【Android开机速度优化简单回顾】


    推荐阅读