Android開機時間分析

葉桐發表於2015-01-16

一、 關於本篇博文

該文件簡單主要描述瞭如何找出開機各個階段耗時情況,以及對開機各個階段的分析方法和如何優化開機時間,減少耗時。便於讀者可以通過此文件瞭解開機時間的各個階段的耗時情況。

二、開機各階段的耗時情況

具體開機時間的優化需要根據開機流程來分析: 找出各個階段的耗時情況 
2.1、zygote階段 
一般有兩個耗時點: 
a). 預載入class/resource的時間。需要確認是否有新增很多系統資源 
b). 這期間是否有很多GC動作 
2.2、SystemServer階段: 
Check各個service開機初始化過程的耗時情況 
通常耗時點: 
a). pms scan package階段: 
b). pms dexopt階段: 
c).其他service初始化過程問題。 
2.3、AMS Ready階段: 
Check耗時情況,通常耗時點:prebootcompleted動作;啟動service/persistent程式;如果沒有客製化動作,基本上無優化空間 
2.4、動畫包過大問題 

如果動畫包過大,播放的圖片過多,解析度過高也會影響開機時間
2.5、StopBootAnimation: 
WMS需要在keyguard, wallpaper, launcher都初始化好的前提下,才會停止開機動畫。 
需要check keyguard是否有做完、Check wallpaper是否有異常、Check launcher 初始化時間。

三、開機時間分析

3.1 cat/proc/bootprof[單位:ms(毫秒)]

從下面的log中我們可以看到核心啟動時間標誌欄位:BOOT_Animation:END


 3.1.1 Preloader&lk time

Preload和lk啟動時間如下:

 

 

3.1.2 Kernel Init

Kernel初始化時間 如下:

 

3.1.3 Mount partition

分割槽掛載時間如下:

 

3.1.4 Android Boot

  3.1.4.1 Pre-load classes

預載入類所消耗的時間

 

 

  3.1.4.2 Package scanning

包掃描時間

 

 

  3.1.4.3 App initializations

AP初始化時間

 

 

3.2 通過新增log得到Package掃描耗時情況

原始碼位於:frameworks/base/service/java/com/android/server/PackageManagerService.java中的scanDirLi()方法中

    private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {

        ......

        if (DEBUG_PACKAGE_SCANNING) {

            Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode

                    + " flags=0x" + Integer.toHexString(flags));

        }

        long startScan,endScan;

        int i;

        for (i=0; i<files.length; i++) {

            File file = new File(dir, files[i]);

            if (!isPackageFilename(files[i])) {

                // Ignore entries which are not apk's

                continue;

            }

            ......

            startScan = SystemClock.uptimeMillis();

            Log.d(TAG,"scan package: " + file.toString() + " , start at: " + startScan + "ms.");

            PackageParser.Package pkg = scanPackageLI(file,

                    flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);

            endScan = SystemClock.uptimeMillis();

            Log.d(TAG,"scan package: " + file.toString() + " , end at: " + endScan + "ms. elapsed time = " + (endScan - startScan) + "ms.");

......

    }

我們可以通過DDMS通過搜尋關鍵字scan package,TAGPackageManager進行檢視。

四、開機時間優化

4.1 cat /proc/mtprof/cputime

 

相關欄位解釋:

  1. Process:程式名
  2. Status:程式狀態,e.g如果程式處於活動狀態值為L(alive),否則為D(dead)
  3. PID、TGID:程式ID和執行緒組ID
  4. CPU Time(ms):真正使用CPU的時間
  5. Elapsed(ms):生命週期內耗時
  6. User:使用者模式時間
  7. Kernel:Kernel模式時間

 

 

4.2 Application init

我們需要防止無關AP在啟動期間進行初始化操作,因為Android在安裝新的apk後可能會啟動一些額外的應用。我們需要找出哪些在系統啟動完成前啟動了哪些應用程式,來進一步確認是否有啟動了一些不需要的AP。

3.2.1在系統啟動期間對應用初始化是因為在ApkAndroidManifest.xmlapplication節點android:persistent的值為true。這個屬性從字面上來說可以理解為可持久,也就是常駐的應用。被該屬性修飾的應用會在系統啟動之後被AM啟動起來。例如PhoneApp在AndroidManifest.xml中註冊了常駐app:

<application android:name=”PhoneApp”

  android:persisitent=”true”

  android:label=”@string/dialerIconLabel”

  android:persisitent=”@drawable/ic_launcher_phone”>

4.2.2一些應用程式的啟動是被其他AndroidAP喚起的如:

  • Services request
  • Content Provider
  • BroadCast Recievier

4.3 啟動動畫

系統安裝了過多的應用很容易影響啟動時間,主要在package scanning和application init。那麼此時Boot animation也會隨著這種影響而進一步影響啟動時間。原因如下:

E.g:如果android啟動動畫佔用10%的CPU,那麼如果系統啟動時間為20sec,那麼動畫佔用的時間就是2s(動畫耗時:20*10%=2),那麼也就是說我們安裝的應用越多,動畫對整個開機過程的影響也就越大。

 

相關文章