Android開機(jī)速度優(yōu)化初探

Android的開機(jī)速度勤讽,基本上沒人說快的蟋座,通常移植完系統(tǒng)后,馬上要看的事情就是優(yōu)化開機(jī)時(shí)間脚牍,以下是簡單回憶以下以前做優(yōu)化的那些事向臀。

一?開機(jī)時(shí)間都花在哪?

優(yōu)化開機(jī)時(shí)間诸狭,通常做的首先是那有有沒有BUG券膀,明顯不合理的先解決,由于開發(fā)階段穩(wěn)定性問題驯遇,一些地方可能延時(shí)加的大芹彬,或者頻率設(shè)的低,先記下來叉庐,后面定期還會再看舒帮。這些先不看的話,一般拿到機(jī)器陡叠,我們統(tǒng)計(jì)開機(jī)時(shí)間玩郊,主要看如下幾個(gè)時(shí)間段分布:

開機(jī)按鍵時(shí)間、亮屏?xí)r間(基本固定枉阵,除非弄錯(cuò)了译红,基本檢查一遍確定)

uboot啟動時(shí)間

內(nèi)核啟動后到bootanim退出時(shí)間


二 內(nèi)核優(yōu)化

可以通過添加打印module init的log,來check每個(gè)module初始化時(shí)的時(shí)間岭妖。從而找到花費(fèi)時(shí)間比較多的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);

三 優(yōu)化方案:

-3?優(yōu)化建議:

preloadClasses()與preloadResources()可以放到兩個(gè)線程里面跑临庇。

修改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 系統(tǒng)剪裁也有助于提高系統(tǒng)的開機(jī)速度

提升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?電源優(yōu)化

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 用來分析內(nèi)核功能假夺, 在kernel cmdline 增加 initcall_debug ,然后dmesg > boot.log? bootgraph.pl boot.log >? boot.svg

1通過一個(gè)比gzip更快的方式去解壓內(nèi)核鏡像;

2 去掉系統(tǒng)中一些不必要的log打诱省已卷;

3 去掉一些系統(tǒng)中不需要的驅(qū)動模塊;

4 啟動時(shí)即以最大頻率(cpu/DDR)且多核一起跑淳蔼;

5 將一些耗時(shí)大侧蘸,對啟動順序沒有要求的驅(qū)動通過異步方式進(jìn)行加載(如下所示)


這里我們主要關(guān)注的是第三個(gè)裁眯,也是優(yōu)化的重點(diǎn)。這部分時(shí)間讳癌,具體都在干啥穿稳,瓶頸是哪,可以通過bootchart很清楚的看到晌坤。以下結(jié)合以前抓的圖逢艘,簡要說一下(圖是很久之前抓的,比較懶骤菠,沒有再跑一遍過程)


上圖中bootanim的退出時(shí)間沒有截出來它改,實(shí)際圖是有的,大約是33s的時(shí)候結(jié)束商乎。

這里分析時(shí)央拖,我們是分了幾個(gè)時(shí)間段:

1 內(nèi)核開始啟動,到init進(jìn)程開始執(zhí)行鹉戚。這個(gè)可以通過log看到鲜戒。

2 init進(jìn)程執(zhí)行,主要是處理init.rc中的命令抹凳,到core和mainl類服務(wù)開始啟動的時(shí)間袍啡,上圖中可以看到,服務(wù)大體都在一個(gè)時(shí)間點(diǎn)起來的却桶,約7.5S時(shí),這之前的一大段空窗期蔗牡,也是要重點(diǎn)看的

3 zygote啟動時(shí)間

4 systemserver中各個(gè)服務(wù)啟動時(shí)間

5 應(yīng)用啟動(systemui/launcher/keyguard..)

以上颖系,具體分析看每段時(shí)間:

第一點(diǎn)另外處理,具體分析打印看是否有異常辩越,這個(gè)值一般是很小的嘁扼,不合理要和BSP同事一起查一下原因。

第二個(gè)主要是init.rc執(zhí)行各種命令黔攒,這個(gè)可以通過在execute_one_command函數(shù)中統(tǒng)計(jì)測量 趁啸,比如大于100ms的命令打印出來,再分析定位原因督惰,這里命令執(zhí)行時(shí)間長基本算BUG不傅,要和BSP工程師一起解決。

第三點(diǎn)主要zygote啟動問題赏胚,主要慢的原因访娶,是加載資源和類庫,這個(gè)要讀nand觉阅,一般卡的時(shí)間比較長崖疤,圖中可以看到秘车,zygote進(jìn)程一溜的小粉紅,說明IO較多劫哼。這個(gè)preload過程消耗的時(shí)間叮趴,在logcat的log中,也會打印的权烧,一般來說眯亦,都是在近10S左右。

第四個(gè)豪嚎,zygote初始化完后搔驼,會fork system_server。 system_server進(jìn)程啟動侈询,耗時(shí)也是較長的舌涨。根據(jù)以前統(tǒng)計(jì)分析的結(jié)果,這里的服務(wù)啟動扔字,基本上都是花在packageManagerService的PackageScan中囊嘉,這又是一個(gè)讀文件,卡在文件讀取中革为,時(shí)間長短扭粱,和預(yù)制app及安裝的app數(shù)量有關(guān)

第五個(gè)時(shí)間,是基本都準(zhǔn)備ready后震檩,啟動launcher等應(yīng)用了琢蛤,啟動完成后,systemServer請求SurfaceFlinger殺了bootanimation抛虏,就啟動完成了博其。

以上時(shí)間中,主要要優(yōu)化的迂猴,還是第三步和第四步的IO慢問題慕淡,其他可優(yōu)化的不多。比如CPU沸毁,常開四核performance模式啟動峰髓,也并沒提升多少,一般我們就不管了這個(gè)了息尺。

咋優(yōu)化携兵?

確定優(yōu)化方向后主要看怎么優(yōu)化這兩段耗時(shí)的地方:

1. Zygote的preload 資源和class

2. PackageManagerService的包掃描

這里的第一個(gè),最早之前有人直接是去掉preload或刪減搂誉,雖然可以加快一點(diǎn)開機(jī)速度眉孩,但是撿了芝麻丟了西瓜,根本不能這樣干~

我們最早做的實(shí)現(xiàn)方式,

2.1 是將preload做并行處理浪汪,畢竟現(xiàn)在都是多核處理器了巴柿,而且是preload是加載后還要解析處理的,并行會有一定幅度提升死遭。

對于包掃描广恢,這個(gè)不好拆成并行任務(wù),不像preload那么簡單干凈呀潭《っ裕考慮過將PackageManager的信息序列化后存起來,下次開機(jī)就不掃了钠署,不過看起來改動有點(diǎn)大糠聪,不太好搞,也放棄了谐鼎。

PackageManagerService掃描舰蟆、檢查APK安裝包信息

2.2 PMS對/system/framework,/system/app狸棍,/data/app身害,/data/app-private目錄中的APK掃描耗費(fèi)了大量的時(shí)間,如果預(yù)置的三方應(yīng)用很多草戈,這樣啟動的時(shí)間就會越長塌鸯。

優(yōu)化建議:

2.3 /system/app下的應(yīng)用,如果是預(yù)置應(yīng)用唐片,在Android.mk建議加上LOCAL_DEX_PREOPT := true控制丙猬,在/system/vendor下的預(yù)置應(yīng)用,如果此應(yīng)用編譯時(shí)間比較長的费韭,也使用上LOCAL_DEX_PREOPT := true

2.4 盡量減少data區(qū)內(nèi)置app的數(shù)量淮悼,這個(gè)會嚴(yán)重影響開機(jī)速度,特別是第一次的開機(jī)速度揽思。放在system的app 盡量生成odex 這樣會加快開機(jī)速度。

最后我們的實(shí)現(xiàn)的方式见擦,就是linux上用的較多的readahead機(jī)制钉汗。具體實(shí)現(xiàn)細(xì)節(jié)就不展開說了,原理就是:

1. 統(tǒng)計(jì)開機(jī)過程中鲤屡,讀取的塊數(shù)據(jù)信息损痰,記錄下來保存

2.再次開機(jī),通過記錄下來的塊數(shù)據(jù)讀取信息酒来,直接起一個(gè)服務(wù)卢未,預(yù)先開始讀,zygote或packagemanagerservice要讀文件的時(shí)候,文件數(shù)據(jù)已經(jīng)在cache中了辽社。

實(shí)際用下來伟墙,這一招特別好,優(yōu)化非常明顯滴铅。以下是實(shí)現(xiàn)了一個(gè)readahead后的bootchart圖:


可以看到:

1. zygote和system_server都提速了

2. zygote和system_server的IO時(shí)間戳葵,都降低非常大

3. 主要IO時(shí)間,跑到readahead進(jìn)程中去了汉匙。

不過拱烁,以上實(shí)現(xiàn),還是有可優(yōu)化的地方:

1. readahead進(jìn)程可以再提前噩翠,在system分區(qū)掛載后立刻啟動戏自,這樣zygote中的IO應(yīng)該可以再減小

2. 對system_server的IO,此時(shí)readahead已經(jīng)結(jié)束了伤锚,按理不應(yīng)該有了擅笔,這里還是有IO,這一般是后裝apk導(dǎo)致见芹,這個(gè)可以把readahead做的更健壯一些剂娄,不要只學(xué)習(xí)開始的一兩次。

其他NB的優(yōu)化

另外還有一個(gè)很NB的技術(shù)玄呛,就是STD阅懦。這個(gè)我們也搞過,花費(fèi)了大量的人力物力徘铝。STD開機(jī)時(shí)間耳胎,不算上uboot時(shí)間的話,基本都是在10S內(nèi)惕它,5~8S之間怕午。不過這么NB的技術(shù),目前基本上也是廢棄了淹魄,用起來問題也挺多的:

1. 開機(jī)時(shí)間少了郁惜,關(guān)機(jī)時(shí)間拉長。

由于是STD(Suspend to Disk)甲锡,關(guān)機(jī)時(shí)需要將內(nèi)存數(shù)據(jù)寫入nand兆蕉,這塊也是挺麻煩的事情

2. 穩(wěn)定性

本身STD弄起來就比較復(fù)雜,BUG挺多的缤沦,另外使用STD虎韵,就相當(dāng)于永不關(guān)機(jī)了,這也太考驗(yàn)系統(tǒng)軟件的穩(wěn)定性了...

3. 沒毛用

?? 一開始還能忽悠客戶缸废,不過后來也沒人怎么關(guān)心這個(gè)feature了包蓝,平白給自己找活干驶社,大家都不樂意使能它了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末测萎,一起剝皮案震驚了整個(gè)濱河市亡电,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绳泉,老刑警劉巖逊抡,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異零酪,居然都是意外死亡冒嫡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門四苇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孝凌,“玉大人,你說我怎么就攤上這事月腋◇凹埽” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵榆骚,是天一觀的道長片拍。 經(jīng)常有香客問我,道長妓肢,這世上最難降的妖魔是什么捌省? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮碉钠,結(jié)果婚禮上纲缓,老公的妹妹穿的比我還像新娘。我一直安慰自己喊废,他們只是感情好休溶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布逞度。 她就那樣靜靜地躺著册踩,像睡著了一般桥氏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓣蛀,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天陆蟆,我揣著相機(jī)與錄音,去河邊找鬼揪惦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛罗侯,可吹牛的內(nèi)容都是我干的器腋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纫塌!你這毒婦竟也來了诊县?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤措左,失蹤者是張志新(化名)和其女友劉穎依痊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怎披,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胸嘁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凉逛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片性宏。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖状飞,靈堂內(nèi)的尸體忽然破棺而出毫胜,到底是詐尸還是另有隱情,我是刑警寧澤诬辈,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布酵使,位于F島的核電站,受9級特大地震影響焙糟,放射性物質(zhì)發(fā)生泄漏口渔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一酬荞、第九天 我趴在偏房一處隱蔽的房頂上張望搓劫。 院中可真熱鬧,春花似錦混巧、人聲如沸枪向。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秘蛔。三九已至,卻和暖如春傍衡,著一層夾襖步出監(jiān)牢的瞬間深员,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工蛙埂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倦畅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓绣的,卻偏偏與公主長得像叠赐,于是被迫代替她去往敵國和親欲账。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容