不可忘記用愛心接待客旅,因?yàn)樵薪哟吐玫模恢挥X就接待了天使坟乾。---希伯來書13:2
問題描述
chrome應(yīng)用冷啟動(dòng)緩慢,跟參考機(jī)相比在luncher界面點(diǎn)擊chrome圖標(biāo)蝶防,有一個(gè)明顯的延遲甚侣,然后chrome才被啟動(dòng)起來。從點(diǎn)擊圖標(biāo)到第一個(gè)界面加載完全顯示间学,問題機(jī)相對(duì)參考機(jī)要慢3s左右渺绒。
初步分析
在 Android 平臺(tái)側(cè)性能優(yōu)化之應(yīng)用啟動(dòng) 一文里遇到過假冷啟動(dòng)引發(fā)的類似問題,按照這個(gè)思路檢查排除了假冷啟動(dòng)的可能菱鸥。
因?yàn)閏hrome都是通過play store跟新到最新版本v58.0.3029.83的宗兼。這也排除了chrome版本不同照成的因素。
參考機(jī)問題機(jī)的硬件參數(shù)有差異氮采,問題機(jī)硬件是工程機(jī)的標(biāo)準(zhǔn)殷绍,而參考機(jī)是出貨的硬件標(biāo)準(zhǔn)。這個(gè)可能存在影響鹊漠,但直覺告訴我不應(yīng)該有3s這么大的影響主到。
systrace分析
經(jīng)過初步分析,該用systrace進(jìn)一步深入分析躯概。采用命令:
./run_systrace.py -a com.android.chrome gfx input view am app dalvik sched freq idle load -o trace.html
分別抓取參考機(jī)和問題機(jī)啟動(dòng)chrome的systrace登钥。
問題機(jī)啟動(dòng)chrome systrace如下:
參考機(jī)啟動(dòng)chrome systrace如下:
注意以上獲取的systrace圖,高亮的部分bindApplication問題機(jī)相對(duì)參考機(jī)多耗時(shí)1s以上娶靡,這個(gè)是非常不合理的牧牢。
放大高亮的bindApplication區(qū)域:
通過上圖可以看到問題機(jī)OpenDexFilesFromOat方法把大部分時(shí)間都消耗在了打開base.apk,這個(gè)base.apk是未經(jīng)過oat優(yōu)化過的chrome apk,而參考機(jī)打開的是base.odex塔鳍。懷疑問題機(jī)上系統(tǒng)對(duì)chrome未做oat優(yōu)化伯铣。但oat優(yōu)化是默認(rèn)開啟的啊,怎么在問題機(jī)上chrome沒有生成對(duì)應(yīng)的odex文件呢轮纫?
為了進(jìn)一步確認(rèn)問題腔寡,我們需要去/data/app/com.android.chrome-1目錄下查看到底有沒有odex文件生成≌仆伲坑爹的是user版本沒有root權(quán)限查看不了放前,只能去單獨(dú)燒錄一個(gè)eng版本的bootimg了。
燒錄eng的boot獲取root權(quán)限查看/data/app/com.android.chrome-1竟然有base.odex糯彬,這遇到了什么鬼犀斋。。情连。
再次抓取此時(shí)問題機(jī)的systrace查看叽粹。
可以看到bindApplication由之前的1.888s變成現(xiàn)在的0.848s。已經(jīng)靠近了參考機(jī)bindApplication花費(fèi)的0.699s却舀,如果再計(jì)算上eng boot對(duì)性能的影響虫几,此時(shí)問題機(jī)bindApplication耗時(shí)應(yīng)該很接近參考機(jī)了。
問題猜想
只是換了一個(gè)boot挽拔,不應(yīng)該出現(xiàn)這種變化辆脸。有沒有可能通過play store更新的chrome需要重啟或者等待一段時(shí)間oat優(yōu)化才會(huì)完成呢?因?yàn)楦峦阠hrome后馬上開始了問題分析螃诅,從之前的systrace看確實(shí)沒有odex文件生成啡氢,而燒錄eng boot后該odex文件就有了,eng boot應(yīng)該不會(huì)影響odex文件的生成术裸,燒錄的過程重啟了手機(jī)倘是,重啟過程很有可能左右該問題的主因。為了驗(yàn)證這個(gè)猜想袭艺,將參考機(jī)問題機(jī)的chrome都卸載更新的版本搀崭,重新通過play store 更新chrome,抓取systrace做對(duì)比參考猾编。
結(jié)果發(fā)現(xiàn)參考機(jī)更新完成后直接測(cè)試沒有出現(xiàn)OpenDexFilesFromOat耗時(shí)過長(zhǎng)問題瘤睹。
在看問題機(jī)同樣也沒有出現(xiàn)OpenDexFilesFromOat耗時(shí)過長(zhǎng)問題。
卸載新版本答倡,重新更新chrome轰传,沒有重啟手機(jī)竟然沒有出現(xiàn)啟動(dòng)異常。難道猜想錯(cuò)了瘪撇,odex的生成壓根與重啟手機(jī)沒有關(guān)系?這就有點(diǎn)費(fèi)解了获茬,跟預(yù)期的不一樣啊港庄,讓人抓狂.
會(huì)不會(huì)是剛刷完機(jī)就復(fù)現(xiàn)問題,此時(shí)后臺(tái)任務(wù)過多锦茁,導(dǎo)致chrome的oat操作沒有完成呢攘轩?
會(huì)不會(huì)是JIT的問題呢叉存?
會(huì)不會(huì)是雖然卸載掉了更新的apk码俩,但某些地方還保留了記錄,再次更新后歼捏,odex會(huì)自動(dòng)生成呢?
在不成難道這是偶現(xiàn)問題稿存?
滿腦子的疑問飛過來,為了解決這些疑問瞳秽,只有在刷機(jī)一次瓣履,從新做實(shí)驗(yàn)。
刷完機(jī)更新完chrome后练俐,為防止偶現(xiàn)問題袖迎,多次抓取了冷啟動(dòng)的systrace,都復(fù)現(xiàn)問題腺晾。
等待30分鐘后燕锥,再次抓取systrace
看來不是后臺(tái)任務(wù)過多,導(dǎo)致chrome的oat操作沒有完成悯蝉。
多次使用chrome,在抓取systrace分析归形。同樣還是有問題,這里圖就不貼了鼻由∠玖瘢看來也不是JIT的問題。
在看重啟手機(jī)后的現(xiàn)象,啟動(dòng)時(shí)間終于正常了蕉世。
終于找到了問題的表因蔼紧,原來通過play store更新chrome應(yīng)用,只有重啟系統(tǒng)才會(huì)去做odex優(yōu)化狠轻。而如果先卸載掉更新的chrome歉井,在重新更新則沒有問題。
刨根溯源
問題原因找到了哈误,那這個(gè)問題是play store的問題還是說系統(tǒng)本身的問題哩至,無法完全確認(rèn),但猜測(cè)很可能是系統(tǒng)本身的問題蜜自,google 不會(huì)留下這么明顯的bug菩貌。因此還需要追溯沒有做odex的原因。
odex的詳細(xì)過程這里不展開講述。后續(xù)在單獨(dú)起一篇做總結(jié)。先給出主要的調(diào)用關(guān)系误算。
沿著上圖最終發(fā)現(xiàn)了問題所在轨淌。原來之前的同事在做開機(jī)優(yōu)化時(shí)做了一個(gè)功能坦胶,將非重要應(yīng)用的dex2oat操作放在了開機(jī)之后奄侠∨钛鳎可是沒有考慮好更新應(yīng)用時(shí)的邏輯處理丛肢,導(dǎo)致了問題的發(fā)生诈乒。本質(zhì)原因找到了罩扇,那么該問題解起來就有方向了。這里涉及到具體的功能怕磨,不在贅述喂饥。
總結(jié)
程序員總愛給程序員挖坑,越向底層的改動(dòng)越要小心肠鲫,牽一發(fā)而動(dòng)全身啊员帮。
性能問題涉及的模塊確實(shí)很多,許多問題總是那么的撲朔迷離导饲,一定要有耐心去分析捞高。
通過分析過程,我們也可以看到dex2oat對(duì)應(yīng)用啟動(dòng)的性能確實(shí)提升巨大渣锦。systrace的好處就是能量化出這種性能差異硝岗。