不可忘記用愛心接待客旅,因?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ī)相對參考機(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ī)相對參考機(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)對chrome未做oat優(yōu)化。但oat優(yōu)化是默認(rèn)開啟的啊,怎么在問題機(jī)上chrome沒有生成對應(yīng)的odex文件呢?
為了進(jìn)一步確認(rèn)問題,我們需要去/data/app/com.android.chrome-1目錄下查看到底有沒有odex文件生成??拥氖莡ser版本沒有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對性能的影響,此時(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做對比參考。
結(jié)果發(fā)現(xiàn)參考機(jī)更新完成后直接測試沒有出現(xiàn)OpenDexFilesFromOat耗時(shí)過長問題。
在看問題機(jī)同樣也沒有出現(xiàn)OpenDexFilesFromOat耗時(shí)過長問題。
卸載新版本,重新更新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),但猜測很可能是系統(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對應(yīng)用啟動(dòng)的性能確實(shí)提升巨大。systrace的好處就是能量化出這種性能差異。