dex2oat對應用啓動性能的影響

不可忘記用愛心接待客旅,因爲曾有接待客旅的,不知不覺就接待了天使。—希伯來書13:2

問題描述

chrome應用冷啓動緩慢,跟參考機相比在luncher界面點擊chrome圖標,有一個明顯的延遲,然後chrome才被啓動起來。從點擊圖標到第一個界面加載完全顯示,問題機相對參考機要慢3s左右。

初步分析

Android 平臺側性能優化之應用啓動 一文裏遇到過假冷啓動引發的類似問題,按照這個思路檢查排除了假冷啓動的可能。
因爲chrome都是通過play store跟新到最新版本v58.0.3029.83的。這也排除了chrome版本不同照成的因素。
參考機問題機的硬件參數有差異,問題機硬件是工程機的標準,而參考機是出貨的硬件標準。這個可能存在影響,但直覺告訴我不應該有3s這麼大的影響。

systrace分析

經過初步分析,該用systrace進一步深入分析。採用命令:

./run_systrace.py -a com.android.chrome gfx input view am app dalvik sched freq idle load -o trace.html

分別抓取參考機和問題機啓動chrome的systrace。

問題機啓動chrome systrace如下:
問題機systrace

參考機啓動chrome systrace如下:
參考機systrace

注意以上獲取的systrace圖,高亮的部分bindApplication問題機相對參考機多耗時1s以上,這個是非常不合理的。
放大高亮的bindApplication區域:
bindApplication對比圖

通過上圖可以看到問題機OpenDexFilesFromOat方法把大部分時間都消耗在了打開base.apk,這個base.apk是未經過oat優化過的chrome apk,而參考機打開的是base.odex。懷疑問題機上系統對chrome未做oat優化。但oat優化是默認開啓的啊,怎麼在問題機上chrome沒有生成對應的odex文件呢?

爲了進一步確認問題,我們需要去/data/app/com.android.chrome-1目錄下查看到底有沒有odex文件生成。坑爹的是user版本沒有root權限查看不了,只能去單獨燒錄一個eng版本的bootimg了。
燒錄eng的boot獲取root權限查看/data/app/com.android.chrome-1竟然有base.odex,這遇到了什麼鬼。。。
再次抓取此時問題機的systrace查看。
燒錄eng boot抓取systrace圖

可以看到bindApplication由之前的1.888s變成現在的0.848s。已經靠近了參考機bindApplication花費的0.699s,如果再計算上eng boot對性能的影響,此時問題機bindApplication耗時應該很接近參考機了。

問題猜想

只是換了一個boot,不應該出現這種變化。有沒有可能通過play store更新的chrome需要重啓或者等待一段時間oat優化纔會完成呢?因爲更新完chrome後馬上開始了問題分析,從之前的systrace看確實沒有odex文件生成,而燒錄eng boot後該odex文件就有了,eng boot應該不會影響odex文件的生成,燒錄的過程重啓了手機,重啓過程很有可能左右該問題的主因。爲了驗證這個猜想,將參考機問題機的chrome都卸載更新的版本,重新通過play store 更新chrome,抓取systrace做對比參考。

結果發現參考機更新完成後直接測試沒有出現OpenDexFilesFromOat耗時過長問題。
在看問題機同樣也沒有出現OpenDexFilesFromOat耗時過長問題。

卸載新版本,重新更新chrome,沒有重啓手機竟然沒有出現啓動異常。難道猜想錯了,odex的生成壓根與重啓手機沒有關係?這就有點費解了,跟預期的不一樣啊,讓人抓狂.


這裏寫圖片描述

會不會是剛刷完機就復現問題,此時後臺任務過多,導致chrome的oat操作沒有完成呢?
會不會是JIT的問題呢?
會不會是雖然卸載掉了更新的apk,但某些地方還保留了記錄,再次更新後,odex會自動生成呢?
在不成難道這是偶現問題?
滿腦子的疑問飛過來,爲了解決這些疑問,只有在刷機一次,從新做實驗。

刷完機更新完chrome後,爲防止偶現問題,多次抓取了冷啓動的systrace,都復現問題。
二次確認

等待30分鐘後,再次抓取systrace
等待30分鐘後

看來不是後臺任務過多,導致chrome的oat操作沒有完成。
多次使用chrome,在抓取systrace分析。同樣還是有問題,這裏圖就不貼了。看來也不是JIT的問題。
在看重啓手機後的現象,啓動時間終於正常了。
重啓手機odex文件生成

終於找到了問題的表因,原來通過play store更新chrome應用,只有重啓系統纔會去做odex優化。而如果先卸載掉更新的chrome,在重新更新則沒有問題。

刨根溯源

問題原因找到了,那這個問題是play store的問題還是說系統本身的問題,無法完全確認,但猜測很可能是系統本身的問題,google 不會留下這麼明顯的bug。因此還需要追溯沒有做odex的原因。
odex的詳細過程這裏不展開講述。後續在單獨起一篇做總結。先給出主要的調用關係。


dex2oat調用關係圖

沿着上圖最終發現了問題所在。原來之前的同事在做開機優化時做了一個功能,將非重要應用的dex2oat操作放在了開機之後。可是沒有考慮好更新應用時的邏輯處理,導致了問題的發生。本質原因找到了,那麼該問題解起來就有方向了。這裏涉及到具體的功能,不在贅述。

總結

程序員總愛給程序員挖坑,越向底層的改動越要小心,牽一髮而動全身啊。
性能問題涉及的模塊確實很多,許多問題總是那麼的撲朔迷離,一定要有耐心去分析。
通過分析過程,我們也可以看到dex2oat對應用啓動的性能確實提升巨大。systrace的好處就是能量化出這種性能差異。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章