Android的开机速度,基本上没人说快的,通常移植完系统后,马上要看的事情就是优化开机时间,以下是简单回忆以下以前做优化的那些事。

开机时间都花在哪?

优化开机时间,通常做的首先是那有有没有BUG,明显不合理的先解决,由于开发阶段稳定性问题,一些地方可能延时加的大,或者频率设的低,先记下来,后面定期还会再看。这些先不看的话,一般拿到机器,我们统计开机时间,主要看如下几个时间段分布:

  1. 开机按键时间、亮屏时间(基本固定,除非弄错了,基本检查一遍确定)
  2. uboot启动时间
  3. 内核启动后到bootanim退出时间

内核优化

可以通过添加打印module init的log,来check每个module初始化时的时间。从而找到花费时间比较多的module:

--- a/init/main.c
+++ b/init/main.c
@@ -785,7 +785,7 @@ int __init_or_module
do_one_initcall(initcall_t fn)if (initcall_blacklisted(fn))return
-EPERM;-      if (initcall_debug)
+      if (1)ret =
do_one_initcall_debug(fn);

优化方案:

  1. 通过一个比gzip更快的方式去解压内核镜像;
  2. 去掉系统中一些不必要的log打印;
  3. 去掉一些系统中不需要的驱动模块;
  4. 启动时即以最大频率(cpu/DDR)且多核一起跑;
  5. 将一些耗时大,对启动顺序没有要求的驱动通过异步方式进行加载(如下所示)

这里我们主要关注的是第三个,也是优化的重点。这部分时间,具体都在干啥,瓶颈是哪,可以通过bootchart很清楚的看到。以下结合以前抓的图,简要说一下(图是很久之前抓的,比较懒,没有再跑一遍过程)

上图中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图:

可以看到:

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开机速度优化简单回顾_freshui的专栏-CSDN博客_android 开机优化

打开 bootchart 收集开机数据

1. adb shell 'touch /data/bootchart/enabled'首先使能 bootchart,bootchart 操作的前提是存在 enable 标记,所以在你不需要收集数据的时候别忘了删除这个标记。2. - sudo apt-get install pybootchartgui- $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.shgrab-bootchart.sh 脚本是 Google 封装的一系列操作的合集跟使用下面手动操作的结果是一样的。* 手动操作1. (可选) echo $TIME_OUT > /data/bootchart/start添加 bootchart timeout 时间2. reboot 重启3. 可以看到 bootchart 生成的数据文件和 log 都被保存在 /data/bootchart 路径下4. tar -zcf boochart.tgz *5. 使用 adb pull 命令将文件拷贝出来

Bug解决办法

设置了 enabled后,重启,发现无法开机了,从内核log看一直在crash

经过一番百度,Google

有的Blog是说把 system/core/init/bootchart.cpp中的

stat.replace(open + 1, close - open - 1, full_name);

删除就好了

我试过,确实,可以开机了

但是又想了想,谷歌会没发现这个问题么?不至于吧

真相只有一个!

然后对比了谷歌7.0 8.1 甚至 9.0 的源代码,开启了漫长2个小时的地毯上搜索....

最终在 Google 的提交记录上找到相关修复提交

system/core/init/Android.mkLOCAL_SANITIZE := integer========》LOCAL_SANITIZE := signed-integer-overflow

有梯子的可以直接看原生提交

https://android-review.googlesource.com/c/platform/system/core/+/445032/2/init/Android.mk#b97

虽然不知道这是什么,但从字面意思大概猜到是和内存溢出有关系吧

LOCAL_SANITIZE

然后再百度搜索一波 LOCAL_SANITIZE signed-integer-overflow

是什么

官方解释

Android 的构建系统还使用了 UBSan 的整数溢出检查功能。UBSan 还支持 unsigned-integer-overflow,这不是严格意义上的未定义行为,但它包含在擦除器中。在生成文件中,可以将 LOCAL_SANITIZE 设置为 signed-integer-overflow、unsigned-integer-overflow 或 combination flag integer,启用 signed-integer-overflow、unsigned-integer-overflow、integer-divide-by-zero、shift-base 和 shift-exponent,以启用这些行为。在 blueprint 文件中,可以将 Misc_undefined 设置为所需的标志,启用这些行为。这些 UBSan 目标,尤其是 unsigned-integer-overflow,广泛用于 mediaserver 组件中,以用来消除任何潜在的整数溢出漏洞

在 Android 中,当出现未定义的行为时,默认的做法是中止程序。但是,从 2016 年 10 月开始,Android 中的 UBSan 将提供一个可选的运行时库,其报告的错误信息将更加详细,包括出现的未定义行为类型、文件和源代码行信息

在 Android.mk 文件中,可通过以下方式启用该库:

LOCAL_SANITIZE:=unsigned-integer-overflow signed-integer-overflow
LOCAL_SANITIZE_DIAG:=unsigned-integer-overflow signed-integer-overflow

在 Linux PC 机上生成 bootchart 图表

PC 机安装 bootchart 工具

sudo apt-get install bootchart
sudo apt-get install pybootchartgui 

生成 bootchar 图表

拷贝 bootchart.tgz 到 PC 中,并执行下面的命令生成图表

bootchart bootchart.tgz

但很有可能会出现如下错误

那么就要更新编译一下自己的bootchartgui工具

由于Ubuntu版本的pybootchartgui不能解析busybox上的bootchart数据,所以这里出现了错误,需要用另外一个版本bootchart2的工具来处理。用git下载bootchart2后需要执行make后才能使用pybootchartgui

git clone https://github.com/xrmx/bootchart.git

下载完成之后,进到目录里面执行make操作

然后执行如下命令即可

python ./bootchart/pybootchartgui.py bootlog.tar.gz

至此bootchart.png文件生成成功

https://elinux.org/images/a/a1/Abs2011_bird_readahead.pdf

Android开机速度优化简单回顾相关推荐

  1. android开机优化服务,Android开机速度优化简单回顾

    Android的开机速度,基本上没人说快的,通常移植完系统后,马上要看的事情就是优化开机时间,以下是简单回忆以下以前做优化的那些事. 开机时间都花在哪? 优化开机时间,通常做的首先是那有有没有BUG, ...

  2. 直播代码,Android开机速度优化

    直播代码,Android开机速度优化的相关方法和代码 cpu升频和task上大核: on init# boost sched tunewrite /dev/stune/schedtune.prefer ...

  3. Android开启odex开关和开机速度优化

    开odex优化首次开机速度,是牺牲空间换取时间的做法,仅限于空间足够的设备.开了odex之后,在编译的时候,整个system image就会被预先优化.由于在启动时不再需要进行app的dex文件进行优 ...

  4. android odex版本调试_Android开启odex开关和开机速度优化

    开odex优化首次开机速度,是牺牲空间换取时间的做法,仅限于空间足够的设备.开了odex之后,在编译的时候,整个system image就会被预先优化.由于在启动时不再需要进行app的dex文件进行优 ...

  5. Android 编译速度优化黑科技 - RocketX

    一.背景描述 二.效果展示 三.思路问题分析与模块搭建 四.问题解决与实现 五.一天一个小惊喜 六.下一步展望 一.背景描述 在项目体量越来越大的情况下,编译速度也随着增长,有时候一个修改需要等待长达 ...

  6. 浅谈Android开机启动速度优化(含应用程序启动速度优化)

    众所周知Android开机启动速度较慢,于是如何加快启动速度便成为一个值得讨论的问题. 在查阅过许多资料后(特别是Google Group的android-platform),我整理总结出下面几点基本 ...

  7. Android开机启动速度优化 app启动速度优化

    众所周知Android开机启动速度较慢,于是如何加快启动速度便成为一个值得讨论的问题.在查阅过许多资料后(特别是Google Group的android-platform),我整理总结出下面几点基本看 ...

  8. 美图Android编译速度优化实践指南

    分享嘉宾:张仙华 美图 资深开发工程师 分享嘉宾:张仙华,美图秀秀android团队资深研发工程师,负责编译加速.性能优化.架构设计等公共基础相关工作 导读:本文的主题是美图秀秀的Android编译速 ...

  9. 优酷 Android 构建速度优化实践

    作者:苏彦郊(木磊) Android 项目一般使用 gradle 作为构建打包工具,gradle 简洁.动态的功能特性为人津津乐道,同样,构建执行速度缓慢的缺陷也一直为人诟病. 近年来,随着优酷功能特 ...

  10. 关于Android 手机 开机速度的优化

    做了这么多年的手机,从来没写过什么文章.以下只是记录下平时自己的修改,仅供参考 关于mtk 平台手机开机速度的优化 第一:尽量减少data区内置app的数量,这个会严重影响开机速度,特别是第一次的开机 ...

最新文章

  1. 听说数据标注行业缺“中立”平台,京东金融竖起了大旗
  2. R使用neuralnet包构建神经网络回归模型并与线性回归模型对比实战
  3. linux 全局搜索文件_Linux笔记之文件搜索1
  4. Spark API 详解/大白话解释 之 map、mapPartitions、mapValues、mapWith、flatMap、flatMapWith、flatMapValues
  5. LaTex安装及使用
  6. 三菱FX3U 485ADP与东元TECO变频器N310通讯程序
  7. 回文字符串判断以及最长回文字符串长度判断
  8. linux安装谷歌浏览器(Chrome)
  9. 深圳大学毕业答辩PPT模板
  10. Java表格Table冻结前几列或者前几行,其余行或列自由滑动。
  11. 计算机大神专业小说,5本高人气系统流小说,无敌满足你,一路爽到底,全部是大神出品...
  12. 深度学习算法(第37期)----如何用强化学习玩游戏?
  13. 什么是虚拟计算机集群
  14. 100天精通Python丨基础知识篇 —— 02、Python和Pycharm(语言特点、学习方法、工具安装)
  15. 如何使用ArcGIS将Excel数据转换为shp格式
  16. Blender 如何添加渲染AO,Bloom~~
  17. csbte路点机器人_《cs1.6》awp地图
  18. C练题笔记之:Leetcode-1460. 通过翻转子数组使两个数组相等
  19. 唐毅:带领和数集团,做好科技成果与创新需求的“摆渡人”
  20. 设定自动弹窗html,javascript如何设置弹窗?

热门文章

  1. 网页动画--鲜花爱心表白动画
  2. 修改bios密码 服务器,为BIOS设置密码让我们的系统更加安全
  3. 怦然心动(Flipped)-5
  4. 7z文件格式及其源码的分析(三)
  5. VBA 中Dim含义
  6. 同时分析多个中通快递单号物流的最后站点和派件员
  7. 博通的网卡linux驱动,CentosRedhat下bcm43142博通无线网卡linux驱动
  8. 如何系统化设计销售队伍规模,确保企业最大的投入产出比
  9. python写一个数字字典生成器
  10. Incorrect string value: '\xF0\x9F\x91\x93\xF0\x9F...' for column 'xxx' at row 1