Android开机速度优化初探

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

一 开机时间都花在哪?

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

开机按键时间、亮屏时间(基本固定,除非弄错了,基本检查一遍确定)

uboot启动时间

内核启动后到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_tfn)

if(initcall_blacklisted(fn))

return

-EPERM;

-if(initcall_debug)

+if(1)

                ret =

do_one_initcall_debug(fn);

三 优化方案:

-3 优化建议:

preloadClasses()与preloadResources()可以放到两个线程里面跑。

修改zygote的nice值,及thread priority。

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#590

中增加如下的修改:

在 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,592SystemClock.uptimeMillis());593preload();594EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,595SystemClock.uptimeMillis()); 前增加修改

/* 20151013 optimize android boot begin */

//get the default priority.

int defaultPriority = Process.getThreadPriority(Process.myPid()) ;

//increase the priority .

Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO) ;


gcAndFinalize(); 增加

Process.setThreadPriority(defaultPriority) ;

/*  20151013 optimize android boot end */


-2 系统剪裁也有助于提高系统的开机速度

提升CPU频率 - 将所有CPU切换至性能模式

adb shell stop perf-hal-1-0

adb shell "echo 1 > /sys/devices/system/cpu/cpu0/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu1/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu2/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu3/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu4/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu5/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu6/online"

adb shell "echo 1 > /sys/devices/system/cpu/cpu7/online"

adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor"

adb shell "echo performance > /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor"

adb shell "echo performance > /sys/class/devfreq/soc:qcom,cpubw/governor"

adb shell "echo performance > /sys/class/devfreq/soc:qcom,mincpubw/governor"

adb shell "echo performance > /sys/class/devfreq/soc:qcom,memlat-cpu0/governor"

adb shell "echo performance > /sys/class/devfreq/soc:qcom, memlat-cpu6/governor"

提升GPU频率

adb shell "echo 0 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel"

adb shell "echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on"

adb shell "echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor"


-1 电源优化

on init

    # Disable UFS powersaving

    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 0

    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 0

    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 0

    write /sys/module/lpm_levels/parameters/sleep_disabled Y

on property:sys.boot_completed=1

    # Enable UFS powersaving

    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1

    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1

    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1

    write /sys/module/lpm_levels/parameters/sleep_disabled N

on charger

    # Enable UFS powersaving

    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1

    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1

    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1

    write /sys/class/typec/port0/port_type sink

    write /sys/module/lpm_levels/parameters/sleep_disabled N


0 bootgraph 用来分析内核功能, 在kernel cmdline 增加 initcall_debug ,然后dmesg > boot.log  bootgraph.pl boot.log >  boot.svg

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或删减,虽然可以加快一点开机速度,但是捡了芝麻丢了西瓜,根本不能这样干~

我们最早做的实现方式,

2.1 是将preload做并行处理,毕竟现在都是多核处理器了,而且是preload是加载后还要解析处理的,并行会有一定幅度提升。

对于包扫描,这个不好拆成并行任务,不像preload那么简单干净。考虑过将PackageManager的信息序列化后存起来,下次开机就不扫了,不过看起来改动有点大,不太好搞,也放弃了。

PackageManagerService扫描、检查APK安装包信息

2.2 PMS对/system/framework,/system/app,/data/app,/data/app-private目录中的APK扫描耗费了大量的时间,如果预置的三方应用很多,这样启动的时间就会越长。

优化建议:

2.3 /system/app下的应用,如果是预置应用,在Android.mk建议加上LOCAL_DEX_PREOPT := true控制,在/system/vendor下的预置应用,如果此应用编译时间比较长的,也使用上LOCAL_DEX_PREOPT := true

2.4 尽量减少data区内置app的数量,这个会严重影响开机速度,特别是第一次的开机速度。放在system的app 尽量生成odex 这样会加快开机速度。

最后我们的实现的方式,就是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了,平白给自己找活干,大家都不乐意使能它了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容