開機啟動花了40多秒,正常開機只需要28秒就能開機起來。
內核的啟動我沒有去分析,另一個同事分析的。我主要是分析從SystemServer啟來到開機動畫結束顯示解鎖界面的這段時間,也就是開機動畫的第三個動畫開始到結束這段時間,這是個比較耗時階段,一般都在17秒左右(見過牛B的手機,只需5秒)。
SystemServer分兩步執行:init1和init2。init1主要是初始化native的服務,代碼在system_init.cpp的system_init,初始化了SurfaceFlinger和SensorService這兩個native的服務。init2啟動的是java的服務,比如ActivityManagerService、WindowManagerService、PackageManagerService等,在這個過程中PackageManagerService用的時間最長,因為PackageManagerService會去掃描特定目錄下的jar包和apk文件。
在開機時間需要40多秒的時,從Log上可以看到,從SurfaceFlinger初始化到動畫結束,要27秒左右的時間,即從SurfaceFlinger::init的LOGI("SurfaceFlinger is starting")這句Log到void SurfaceFlinger::bootFinished()的LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ),需要27秒左右的時間,這顯然是太長了,但到底是慢在哪了呢?應該在個中間的點,二分一下,於是想到了以啟動服務前後作為分隔:是服務啟動慢了,還是在服務啟動後的這段時間慢?以ActivityManagerService的Slog.i(TAG, "System now ready")的這句Log為分割點,對比了一下,在從SurfaceFlinger is starting到System now ready多了7秒左右的時間,這說明SystemServer在init1和init2過程中啟動慢了,通過排查,發現在init1啟動的時候,花了7秒多的時間,也就是system_init的LOGI("Entered system_init()")到LOGI("System server: starting Android runtime.n")這段時間用了7秒多,而正常情況是400毫秒便可以初始化完,通過添加Log看到,在SensorService啟動時,用了比較長的時間。
不斷的添加Log發現,在啟動SensorService時候,關閉設備文件變慢了,每次關閉一個/dev/input/下的設備文件需要100ms左右,而SensorService有60~70次的關閉文件,大概有7s左右的時間。
調用流程是:
frameworks/base/cmds/system_server/library/system_init.cpp: system_init->SensorService::instantiate
frameworks/native/services/sensorservice/SensorService.cpp: void SensorService::onFirstRef()->SensorDevice& dev(SensorDevice::getInstance())
hardware/libsensors/SensorDevice.cpp: SensorDevice::SensorDevice()->sensors_open
hardware/libsensors/sensors.cpp: open_sensors->sensors_poll_context_t
sensors_poll_context_t執行打開每個傳感器設備時,遍歷/dev/input/目錄下的設備文件,以匹配當前需要打開的設備,遍歷文件是在
hardware/libsensors/SensorBase.cpp的openInput下實現,如果打開的設備文件不是正在打開的設備文件,會執行下面語句的else部分:
if (!strcmp(name, inputName)) {
strcpy(input_name, filename);
break;
} else {
close(fd);
fd = -1;
}
close每次需要100ms左右,每次打開傳感器部分都執行去這樣的操作,導致了在這有大概7s左右的延遲。
優化完這段時間後,系統啟動變快了7秒,但還是慢,因為對比可以發現:
開機28秒:
04-16 16:14:22.205 140 343 I SurfaceFlinger: Using composer version 1.0
04-16 16:14:34.167 527 542 I ActivityManager: System now ready
04-16 16:14:39.089 140 605 I SurfaceFlinger: Boot is finished (16985 ms)
開機34秒:
04-18 15:32:55.565 I/SurfaceFlinger( 242): SurfaceFlinger is starting
04-18 15:33:05.214 I/ActivityManager( 622): System now ready
04-18 15:33:17.658 I/SurfaceFlinger( 242): Boot is finished (22091 ms)
可見還是慢了6秒。但這6秒慢在了似乎是在服務啟動後的時間,這個時候比較難分析了,原因是這是所有的服務起來了,而且發出了bootcomplete廣播,應用也開始起來,但還沒用解鎖,開始以為是Launcher起來慢了,但換了一個Google原始的Launcher進去,並沒有變快。
我們用兩個版本的手機,W制式的跟TD的,過來幾天發現TD的手機比W的開機快,而且TD的28秒左右能起來,但W的卻要34秒,問了一下驅動的同事,W跟TD的並沒有什麼區別,所以除了Modem不一樣以外,其他的都一樣。找了一天,依然毫無結果。從Log中看,都只這慢一點,那慢一點,只有在Packmanager在掃描包的過程中,W+GSM需要6秒左右的時間,而TD+GSM只需要3秒左右的時間,但也不至於花費6秒的時間。但軟件版本是一樣的,猜測是硬件的問題,但硬件都是一樣的,除了Modem不一樣以外,開始懷疑Modem,W+GSM是正常的開機模式,而TD+GSM卻是在mbp模式下開機的,弄成一樣的開機模式,依然沒有改變兩個開機時間。到最才發現W的手機用的是16G的EMMC,而TD的手機用的是32G的EMMC,而且32G的EMMC比16G的EMMC讀寫速度快,以為找到了原因,結果很失望,通過電子的同事,把EMMC對換了一下,開機速度還是沒有變化,快的還是快,慢的還是這麼慢,暈,白高興了一場,但至少也發現了EMMC讀寫速度是不一樣的,至少不是一無所獲。折騰了一天,也就得到個這樣的結果!!!
過來一段時間以後,發現W的手機也變好了,28秒就能開機起來了,這是多麼興奮的是呀,不用解,問題就好了!可惜好景不長,沒過多久,發現W的手機開機時間又變回33秒了,這還真讓人郁悶,於是用抓Log看下,結果就詫異了,從SurfaceFlinger is starting到Boot is finished用是時間還是17秒左右,並沒有變長呀!這是什麼原因呢?同過實時的抓取LOG發現,28秒能開機起來的時候,Boot is finished這句LOG一打出,解到了解鎖界面,但33秒是,卻還等了一會才有解鎖界面,難怪!一問,才知道他們在Boot is finished加了一句usleep(5*1000*1000),原因是不這樣做,解鎖在開機起來後滑不動或者會卡頓,所以加了5秒的延遲