本文是《Android內(nèi)核開發(fā)》系列的第八篇文章,本文主要關(guān)注如何分析Android系統(tǒng)的啟動(dòng)log,學(xué)會(huì)通過搜索重要的TAG標(biāo)簽,找到Android啟動(dòng)過程中的重要節(jié)點(diǎn)。
龍子湖ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!要學(xué)會(huì)分析系統(tǒng)的啟動(dòng)log信息,首先得了解Android系統(tǒng)的啟動(dòng)過程,建議先閱讀《Android內(nèi)核開發(fā):圖解Android系統(tǒng)的啟動(dòng)過程》這篇文章,它詳細(xì)介紹了Android系統(tǒng)的啟動(dòng)過程。其次,你需要知道如何抓取系統(tǒng)啟動(dòng)log信息,建議閱讀《Android內(nèi)核開發(fā):如何統(tǒng)計(jì)系統(tǒng)啟動(dòng)時(shí)間》這篇文章,它詳細(xì)地介紹了如何抓取系統(tǒng)的啟動(dòng)log信息。
本文在這2篇文章的基礎(chǔ)上,進(jìn)一步介紹如何深入地分析系統(tǒng)啟動(dòng)log信息,找出Android啟動(dòng)啟動(dòng)過程中每一個(gè)部分所消耗的具體時(shí)間節(jié)點(diǎn)。
首先,我們給出一張比較全面的Android系統(tǒng)啟動(dòng)圖(來自Embeded Android):
根據(jù)上述Android的啟動(dòng)框圖,我們可以順序地列出Android系統(tǒng)啟動(dòng)中涉及的幾個(gè)關(guān)鍵步驟:
(1) Linux內(nèi)核的啟動(dòng)
(2) Init程序啟動(dòng),并啟動(dòng)各個(gè)本地服務(wù)(如 healthd, debuggerd等)
(3) Zygote進(jìn)程啟動(dòng)
(4) Zygote進(jìn)程初始化工作(preload class/resource)
(5) SystemServer進(jìn)程啟動(dòng),并啟動(dòng)各個(gè)Java服務(wù)(如 ActivityManager, PackageManager等 )
(7) 啟動(dòng)結(jié)束的標(biāo)志點(diǎn)
如果我們能夠從啟動(dòng)log信息中找出上述這些關(guān)鍵步驟的時(shí)間節(jié)點(diǎn),也就可以很清晰地得到Android系統(tǒng)啟動(dòng)過程中各個(gè)模塊消耗的時(shí)間了,在做系統(tǒng)啟動(dòng)優(yōu)化時(shí),也就知道該去優(yōu)化哪些耗時(shí)的模塊了,同樣,在分析系統(tǒng)啟動(dòng)bug的時(shí)候,也就知道到底哪里出了問題了。
下面,我們以高通的APQ8064開發(fā)板(Android 4.4.2)的啟動(dòng)log信息為例來分析(這些log文件上傳到我的Github上了:https://github.com/Jhuster/AOSP/tree/master/logs/APQ8064),其實(shí)各個(gè)Android系統(tǒng)都有類似的log輸出,我們只需重點(diǎn)掌握關(guān)鍵節(jié)點(diǎn)的TAG和分析方法。
1. 配置系統(tǒng)的log輸出
(1) 在內(nèi)核log信息中打印出時(shí)間信息
在Linux kernel源碼樹中執(zhí)行 make menuconfig,勾選下面的選項(xiàng):
"Kernel hacking" -> "Show timing information on printks"
(2) 將init進(jìn)程的詳細(xì)log輸出到dmesg文件中
修改/system/core/rootdir/init.rc,把loglevel從3改為7
2. 抓取系統(tǒng)啟動(dòng)的log信息
前面的文章已經(jīng)介紹過,Android系統(tǒng)啟動(dòng)的log分為Linux內(nèi)核的log和Android Logger系統(tǒng)的log,
抓取的方法如下:
$ adb shell dmesg > dmesg.txt
$ adb logcat -d -v time -b "main" > main.txt
$ adb logcat -d -v time -b "system" > system.txt
$ adb logcat -d -v time -b "events" > events.txt
3. 分析log信息
(1) Linux內(nèi)核的啟動(dòng)
Linux內(nèi)核啟動(dòng)的log都位于dmesg.txt文件中,從log文件開始直到出現(xiàn)下面這條消息則標(biāo)志著Linux內(nèi)核已經(jīng)完成了啟動(dòng):
"Freeing init memory"
因此,我們從dmesg.txt文件中即可得到APQ8064開發(fā)板的Linux內(nèi)核啟動(dòng)只用了6.613s,如圖所示:
(2) Init程序啟動(dòng),并啟動(dòng)各個(gè)本地服務(wù)(如 healthd, debuggerd等)
Init程序的log信息也位于dmesg.txt文件中,我們可以通過檢索“init”找到該程序的打印消息。
通過檢索“init starting”,我們可以找到init進(jìn)程啟動(dòng)了哪些本地服務(wù),如:
(3) Zygote進(jìn)程啟動(dòng)
zygote進(jìn)程是在init進(jìn)程中啟動(dòng)的,因此,我們從上面init進(jìn)程的輸出log中,檢索"zygote"就可以找到zygote進(jìn)程何時(shí)啟動(dòng)的,如圖所示:
(4) Zygote進(jìn)程初始化工作(preload class/resource)
Zygote進(jìn)程所輸出的log信息被放到/dev/log/main文件中了,因此,我們需要檢索main.txt得到Zygote的log信息。
由于后續(xù)所有的Android應(yīng)用程序都是從Zygote進(jìn)程fork出來的,Android系統(tǒng)為了提高應(yīng)用程序的啟動(dòng)速度,會(huì)在Zygote進(jìn)程初始化過程中加載一些常用的java class和資源文件到進(jìn)程的內(nèi)存中,從而共享常用的class和resourse資源。這個(gè)過程我們可以通過檢索"preload"標(biāo)簽得到這個(gè)過程所消耗的時(shí)間,如圖所示:
(5) SystemServer進(jìn)程啟動(dòng),并啟動(dòng)各個(gè)Java服務(wù)(如 ActivityManager, PackageManager等 )
Zygote完成了初始化工作后就啟動(dòng)SystemServer進(jìn)程了,SystemServer進(jìn)程的log信息被放到了/dev/log/system文件中了,因此,我們需要檢索system.txt文件得到SystemServer的log信息,如圖所示:
(7) 啟動(dòng)結(jié)束的標(biāo)志點(diǎn)
《Android內(nèi)核開發(fā):如何統(tǒng)計(jì)系統(tǒng)啟動(dòng)時(shí)間》這篇文章已經(jīng)詳細(xì)地介紹了如何找到啟動(dòng)結(jié)束的時(shí)間,這里選取其中一種方法再復(fù)述一遍,就是檢索dmesg文件的 "boot_completed" 標(biāo)志,如圖所示,我們知道了整個(gè)系統(tǒng)一共耗時(shí)29.913s完成啟動(dòng):
4. 小結(jié)
關(guān)于深度解析Android系統(tǒng)的啟動(dòng)log信息就介紹到這里了,有任何疑問或者建議歡迎留言或者來信lujun.hust@gmail.com交流,或者關(guān)注我的新浪微博 @盧_俊 獲取最新的文章和資訊。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。