Android 8.0 : 進程模型淺析(一)(仮)

前言

Android 8.0 / 8.1是目前 Android 最新的正式發行版智能手機操做系統,2017年3月21日 Google 爲開發者推出了新的 Android O 首個開發者預覽版,2017 Google I/O 開發者大會上發佈了第二個Android O開發者預覽。2017年8月22日,谷歌正式發佈了Android 8.0的正式版,其正式名稱爲:Android Oreo(奧利奧)。2017年12月5日谷歌正式發佈了Android 8.1的正式版。在最近的 Android 版本更新中,能夠看得出來,Google 已經更加註重 Android 的流暢性和續航能力等性能,這個傾斜會讓 Android 的用戶體驗變得愈來愈好。html

聽說谷歌重寫的Android的底層源碼,我在查看進程時就發現了一些顯著的不一樣,固然我沒有使用實機操做,不知道這個現象是否正常。如下爲我平常使用的Sony Xperia Z5 Premium 搭載 Android 7.1.1 和AVD上的一個Android 8.0 的虛擬在adb shell中查看進程的不一樣之處。java

能夠看到AVD已經再也不顯示 root system 等USER的進程了,表頭也發生了變化,sh進程NAME值爲sh,而非7.0的/system/bin/sh。linux

Android系統架構

Android系統架構

Android 操做系統是一個軟件組件的棧,在架構圖中它大體能夠分爲五個部分和四個主要層。android


Linux內核

在全部層的最底下是 Linux - 包括大約115個補丁的 Linux 3.6。它提供了基本的系統功能,好比進程管理,內存管理,設備管理(如攝像頭,鍵盤,顯示器)。同時,內核處理全部 Linux 所擅長的工做,如網絡和大量的設備驅動,從而避免兼容大量外圍硬件接口帶來的不便。git


程序庫

在 Linux 內核層的上面是一系列程序庫的集合,包括開源的 Web 瀏覽器引擎 Webkit ,知名的 libc 庫,用於倉庫存儲和應用數據共享的 SQLite 數據庫,用於播放、錄製音視頻的庫,用於網絡安全的 SSL 庫等。web


Android程序庫

這個類別包括了專門爲 Android 開發的基於 Java 的程序庫。這個類別程序庫的示例包括應用程序框架庫,如用戶界面構建,圖形繪製和數據庫訪問。一些 Android 開發者可用的 Android 核心程序庫總結以下:算法

  • android.app - 提供應用程序模型的訪問,是全部 Android 應用程序的基石。
  • android.content - 方便應用程序之間,應用程序組件之間的內容訪問,發佈,消息傳遞。
  • android.database - 用於訪問內容提供者發佈的數據,包含 SQLite 數據庫管理類。
  • android.opengl - OpenGL ES 3D 圖片渲染 API 的 Java 接口。
  • android.os - 提供應用程序訪問標註操做系統服務的能力,包括消息,系統服務和進程間通訊。
  • android.text - 在設備顯示上渲染和操做文本。
  • android.view - 應用程序用戶界面的基礎構建塊。
  • android.widget - 豐富的預置用戶界面組件集合,包括按鈕,標籤,列表,佈局管理,單選按鈕等。
  • android.webkit - 一系列類的集合,容許爲應用程序提供內建的 Web 瀏覽能力。

看過了 Android 運行層內的基於 Java 的核心程序庫,是時候關注一下 Android 軟件棧中的基於 C/C++ 的程序庫。shell


Android運行時

這是架構中的第三部分,自下而上的第二層。這個部分提供名爲 Dalvik 虛擬機的關鍵組件,相似於 Java 虛擬機,但專門爲 Android 設計和優化。數據庫

Dalvik 虛擬機使得能夠在 Java 中使用 Linux 核心功能,如內存管理和多線程。Dalvik 虛擬機使得每個 Android 應用程序運行在本身獨立的虛擬機進程。瀏覽器

Android 運行時同時提供一系列核心的庫來爲 Android 應用程序開發者使用標準的 Java 語言來編寫 Android 應用程序。


應用框架

應用框架層以 Java 類的形式爲應用程序提供許多高級的服務。應用程序開發者被容許在應用中使用這些服務。

  • 活動管理者 - 控制應用程序生命週期和活動棧的全部方面。
  • 內容提供者 - 容許應用程序之間發佈和分享數據。
  • 資源管理器 - 提供對非代碼嵌入資源的訪問,如字符串,顏色設置和用戶界面佈局。
  • 通知管理器 - 容許應用程序顯示對話框或者通知給用戶。
  • 視圖系統 - 一個可擴展的視圖集合,用於建立應用程序用戶界面。

應用程序

頂層中有全部的 Android 應用程序。你寫的應用程序也將被安裝在這層。這些應用程序包括通信錄,瀏覽器,遊戲等。

Android進程

查看Android進程

Android是基於Linux的,可是沒有terminal因此咱們查看Android進程須要使用adb中的adb shell進入手機,再使用ps指令來查看,如前言所示。

Android進程

當某個應用組件啓動且該應用沒有運行其餘任何組件時,Android 系統會使用單個執行線程爲應用啓動新的 Linux 進程。

默認狀況下,同一應用的全部組件均在相同的進程中運行,且大多數應用都不會改變這一點。 可是,若是您發現須要控制某個組件所屬的進程,則可在清單文件中執行此操做。

若是內存不足,而其餘爲用戶提供更緊急服務的進程又須要內存時,Android 可能會決定在某一時刻關閉某一進程。在被終止進程中運行的應用組件也會隨之銷燬。 當這些組件須要再次運行時,系統將爲它們重啓進程。

決定終止哪一個進程時,Android 系統將權衡它們對用戶的相對重要程度。例如,相對於託管可見 Activity 的進程而言,它更有可能關閉託管屏幕上再也不可見的 Activity 的進程。 所以,是否終止某個進程的決定取決於該進程中所運行組件的狀態。 

進程生命週期

Android 系統將盡可能長時間地保持應用進程,但爲了新建進程或運行更重要的進程,最終須要移除舊進程來回收內存。 爲了肯定保留或終止哪些進程,系統會根據進程中正在運行的組件以及這些組件的狀態,將每一個進程放入「重要性層次結構」中。 必要時,系統會首先消除重要性最低的進程,而後是重要性略遜的進程,依此類推,以回收系統資源。

Android系統共有五種等級的進程

重要性層次結構一共有 5 級。如下列表按照重要程度列出了各種進程(第一個進程最重要,將是最後一個被終止的進程):

  1. 前臺進程

    用戶當前操做所必需的進程。若是一個進程知足如下任一條件,即視爲前臺進程:

    一般,在任意給定時間前臺進程都爲數很少。只有在內存不足以支持它們同時繼續運行這一萬不得已的狀況下,系統纔會終止它們。 此時,設備每每已達到內存分頁狀態,所以須要終止一些前臺進程來確保用戶界面正常響應。

  2. 可見進程

    沒有任何前臺組件、但仍會影響用戶在屏幕上所見內容的進程。 若是一個進程知足如下任一條件,即視爲可見進程:

    • 託管不在前臺、但仍對用戶可見的 Activity(已調用其 onPause() 方法)。例如,若是前臺 Activity 啓動了一個對話框,容許在其後顯示上一 Activity,則有可能會發生這種狀況。
    • 託管綁定到可見(或前臺)Activity 的 Service

    可見進程被視爲是極其重要的進程,除非爲了維持全部前臺進程同時運行而必須終止,不然系統不會終止這些進程。

  3. 服務進程

    正在運行已使用 startService() 方法啓動的服務且不屬於上述兩個更高類別進程的進程。儘管服務進程與用戶所見內容沒有直接關聯,可是它們一般在執行一些用戶關心的操做(例如,在後臺播放音樂或從網絡下載數據)。所以,除非內存不足以維持全部前臺進程和可見進程同時運行,不然系統會讓服務進程保持運行狀態。

  4. 後臺進程

    包含目前對用戶不可見的 Activity 的進程(已調用 Activity 的 onStop() 方法)。這些進程對用戶體驗沒有直接影響,系統可能隨時終止它們,以回收內存供前臺進程、可見進程或服務進程使用。 一般會有不少後臺進程在運行,所以它們會保存在 LRU (最近最少使用)列表中,以確保包含用戶最近查看的 Activity 的進程最後一個被終止。若是某個 Activity 正確實現了生命週期方法,並保存了其當前狀態,則終止其進程不會對用戶體驗產生明顯影響,由於當用戶導航回該 Activity 時,Activity 會恢復其全部可見狀態。 有關保存和恢復狀態的信息,請參閱 Activity文檔。

  5. 空進程

    不含任何活動應用組件的進程。保留這種進程的的惟一目的是用做緩存,以縮短下次在其中運行組件所需的啓動時間。 爲使整體系統資源在進程緩存和底層內核緩存之間保持平衡,系統每每會終止這些進程。 

進程優先級的定義

OOM adjustments與 Process Importance決定了進程在調用中的優先級。

ADJ值定義在frameworks\base\services\core\java\com\android\server\am\ProcessList.java中

    // OOM adjustments for processes in various states:

    // Uninitialized value for any major or minor adj fields
    static final int INVALID_ADJ = -10000;

    // Adjustment used in certain places where we don't know it yet.
    // (Generally this is something that is going to be cached, but we
    // don't know the exact value in the cached range to assign yet.)
    static final int UNKNOWN_ADJ = 1001;

    // This is a process only hosting activities that are not visible,
    // so it can be killed without any disruption.
    static final int CACHED_APP_MAX_ADJ = 906;
    static final int CACHED_APP_MIN_ADJ = 900;

    // The B list of SERVICE_ADJ -- these are the old and decrepit
    // services that aren't as shiny and interesting as the ones in the A list.
    static final int SERVICE_B_ADJ = 800;

    // This is the process of the previous application that the user was in.
    // This process is kept above other things, because it is very common to
    // switch back to the previous app.  This is important both for recent
    // task switch (toggling between the two top recent apps) as well as normal
    // UI flow such as clicking on a URI in the e-mail app to view in the browser,
    // and then pressing back to return to e-mail.
    static final int PREVIOUS_APP_ADJ = 700;

    // This is a process holding the home application -- we want to try
    // avoiding killing it, even if it would normally be in the background,
    // because the user interacts with it so much.
    static final int HOME_APP_ADJ = 600;

    // This is a process holding an application service -- killing it will not
    // have much of an impact as far as the user is concerned.
    static final int SERVICE_ADJ = 500;

    // This is a process with a heavy-weight application.  It is in the
    // background, but we want to try to avoid killing it.  Value set in
    // system/rootdir/init.rc on startup.
    static final int HEAVY_WEIGHT_APP_ADJ = 400;

    // This is a process currently hosting a backup operation.  Killing it
    // is not entirely fatal but is generally a bad idea.
    static final int BACKUP_APP_ADJ = 300;

    // This is a process only hosting components that are perceptible to the
    // user, and we really want to avoid killing them, but they are not
    // immediately visible. An example is background music playback.
    static final int PERCEPTIBLE_APP_ADJ = 200;

    // This is a process only hosting activities that are visible to the
    // user, so we'd prefer they don't disappear.
    static final int VISIBLE_APP_ADJ = 100;
    static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;

    // This is the process running the current foreground app.  We'd really
    // rather not kill it!
    static final int FOREGROUND_APP_ADJ = 0;

    // This is a process that the system or a persistent process has bound to,
    // and indicated it is important.
    static final int PERSISTENT_SERVICE_ADJ = -700;

    // This is a system persistent process, such as telephony.  Definitely
    // don't want to kill it, but doing so is not completely fatal.
    static final int PERSISTENT_PROC_ADJ = -800;

    // The system process runs at the default adjustment.
    static final int SYSTEM_ADJ = -900;

    // Special code for native processes that are not being managed by the system (so
    // don't have an oom adj assigned by the system).
    static final int NATIVE_ADJ = -1000;

 

ADJ值越小則優先度越高,例如INVALID和NATIVE的ADJ值在Android 8.0中爲-10000和-1000,優先度最高,系統不會去關閉它。緊隨其後的是SYSTEM,ADJ值爲-900。

ADJ值

類型

-10000

INVALID 未定義

-1000

NATIVE 本機持有的特殊代碼
-900
SYSTEM
-800
PERSISTENT_PROC 系統持續進程(電話)
-700
PERSISTENT_SERVICE 系統服務進程
0
FOREGROUND_APP 前臺應用
100
VISIBLE_APP 可見應用
200
PERCEPTIBLE_APP 後臺應用
300
BACKUP_APP 備份進程
400
HEAVY_WEIGHT_APP 重量級後臺進程
500
SERVICE 服務進程
600
HOME_APP 主進程
700
PREVIOUS_APP 上一個進程
800
SERVICE_B 舊的服務進程B列表
900
CACHED_APP_MIN
906
CACHED_APP_MAX
1001
UNKNOWN
99(PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1)
VISIBLE_APP_LAYER_MAX

 

Android 進程級別 和 oom_adj對應關係

 一 : 前臺進程 (Active Process): oom_adj爲0。

         前臺進程包括 : 1 : 活動 正在前臺接收用戶輸入  

                               2:活動、服務與廣播接收器正在執行一個onReceive事件的處理函數

                               3: 服務正在運行 onStart、onCreate或onDestroy事件處理函數。

二 : 已啓動服務的進程(Started Service Process) :oom_adj值爲0,這類進程包含一個已啓動的服務。 服務並不直接與用戶輸入交互,所以服務的優先級

        低於可見活動的優先級,可是,已啓動服務的進程任被認爲是前臺進程,只有在活動以及可見活動須要資源時,已啓動服務的進程纔會被殺死。

三 :可見進程 (Visible Process): oom_adj 爲 100。活動是可見的,但並不在前臺,或者不響應用戶的輸入。例如,活動被非全屏或者透明的活動所遮擋。

//如下爲舊版本

四 :後臺進程 (Backgroud Process): oom_adj 值爲 2,這類進程不包含任何可見的活動與啓動的服務。一般大量後臺進程存在時,系統會採用(last-seen-first-kill)後見先殺的方式,釋放資源爲前臺進程使用。

五 :主界面 (home process): oom_adj 爲 4

六 :隱藏進程 (hidden process): oom_adj爲 7

七 :內容提供者 (content provider):oom_adj 爲 14

八 :空進程 (Empty process):oom_adj爲 15


Process Importance定義在frameworks/base/core/java/android/app/ActivityManager.java類中:

        /**
         * Constant for {@link #importance}: This process is running the
         * foreground UI; that is, it is the thing currently at the top of the screen
         * that the user is interacting with.
         */
        public static final int IMPORTANCE_FOREGROUND = 100;

        /**
         * Constant for {@link #importance}: This process is running a foreground
         * service, for example to perform music playback even while the user is
         * not immediately in the app.  This generally indicates that the process
         * is doing something the user actively cares about.
         */
        public static final int IMPORTANCE_FOREGROUND_SERVICE = 125;

        /**
         * Constant for {@link #importance}: This process is running the foreground
         * UI, but the device is asleep so it is not visible to the user.  This means
         * the user is not really aware of the process, because they can not see or
         * interact with it, but it is quite important because it what they expect to
         * return to once unlocking the device.
         */
        public static final int IMPORTANCE_TOP_SLEEPING = 150;

        /**
         * Constant for {@link #importance}: This process is running something
         * that is actively visible to the user, though not in the immediate
         * foreground.  This may be running a window that is behind the current
         * foreground (so paused and with its state saved, not interacting with
         * the user, but visible to them to some degree); it may also be running
         * other services under the system's control that it inconsiders important.
         */
        public static final int IMPORTANCE_VISIBLE = 200;

        /**
         * Constant for {@link #importance}: {@link #IMPORTANCE_PERCEPTIBLE} had this wrong value
         * before {@link Build.VERSION_CODES#O}.  Since the {@link Build.VERSION_CODES#O} SDK,
         * the value of {@link #IMPORTANCE_PERCEPTIBLE} has been fixed.
         *
         * <p>The system will return this value instead of {@link #IMPORTANCE_PERCEPTIBLE}
         * on Android versions below {@link Build.VERSION_CODES#O}.
         *
         * <p>On Android version {@link Build.VERSION_CODES#O} and later, this value will still be
         * returned for apps with the target API level below {@link Build.VERSION_CODES#O}.
         * For apps targeting version {@link Build.VERSION_CODES#O} and later,
         * the correct value {@link #IMPORTANCE_PERCEPTIBLE} will be returned.
         */
        public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;

        /**
         * Constant for {@link #importance}: This process is not something the user
         * is directly aware of, but is otherwise perceptible to them to some degree.
         */
        public static final int IMPORTANCE_PERCEPTIBLE = 230;

        /**
         * Constant for {@link #importance}: {@link #IMPORTANCE_CANT_SAVE_STATE} had
         * this wrong value
         * before {@link Build.VERSION_CODES#O}.  Since the {@link Build.VERSION_CODES#O} SDK,
         * the value of {@link #IMPORTANCE_CANT_SAVE_STATE} has been fixed.
         *
         * <p>The system will return this value instead of {@link #IMPORTANCE_CANT_SAVE_STATE}
         * on Android versions below {@link Build.VERSION_CODES#O}.
         *
         * <p>On Android version {@link Build.VERSION_CODES#O} after, this value will still be
         * returned for apps with the target API level below {@link Build.VERSION_CODES#O}.
         * For apps targeting version {@link Build.VERSION_CODES#O} and later,
         * the correct value {@link #IMPORTANCE_CANT_SAVE_STATE} will be returned.
         *
         * @hide
         */
        public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;

        /**
         * Constant for {@link #importance}: This process is running an
         * application that can not save its state, and thus can't be killed
         * while in the background.
         * @hide
         */
        public static final int IMPORTANCE_CANT_SAVE_STATE= 270;

        /**
         * Constant for {@link #importance}: This process is contains services
         * that should remain running.  These are background services apps have
         * started, not something the user is aware of, so they may be killed by
         * the system relatively freely (though it is generally desired that they
         * stay running as long as they want to).
         */
        public static final int IMPORTANCE_SERVICE = 300;

        /**
         * Constant for {@link #importance}: This process process contains
         * cached code that is expendable, not actively running any app components
         * we care about.
         */
        public static final int IMPORTANCE_CACHED = 400;

        /**
         * @deprecated Renamed to {@link #IMPORTANCE_CACHED}.
         */
        public static final int IMPORTANCE_BACKGROUND = IMPORTANCE_CACHED;

        /**
         * Constant for {@link #importance}: This process is empty of any
         * actively running code.
         * @deprecated This value is no longer reported, use {@link #IMPORTANCE_CACHED} instead.
         */
        @Deprecated
        public static final int IMPORTANCE_EMPTY = 500;

        /**
         * Constant for {@link #importance}: This process does not exist.
         */
        public static final int IMPORTANCE_GONE = 1000;

IMPORTANCE值也是越小優先度越高。

IMPORTANCE_FOREGROUND 意味着這個進程正在運行前臺UI,也就是說,它是當前在屏幕頂部的東西,用戶正在進行交互的而進程,即以前提到的前臺進程。

IMPORTANCE_FOREGROUND_SERVICE前臺服務,即便用戶不是在應用中時也執行音樂播放,這通常表示該進程正在作用戶積極關心的事情。

在這裏咱們發現了一個Android 8.0不一樣以往的地方新增了IMPORTANCE_CACHED = 400的定義,然後臺進程IMPORTANCE_BACKGROUND值與其相同。

IMPORTANCE值 屬性
100  
FOREGROUND
125  
FOREGROUND_SERVICE
130  
PERCEPTIBLE_PRE_26
170  
CANT_SAVE_STATE_PRE_26
150  
TOP_SLEEPING
200  
VISIBLE
230  
PERCEPTIBLE
270  
CANT_SAVE_STATE
300  
SERVICE
400
CACHED & BACKGROUND
500
EMPTY
1000
GONE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

進程回收機制

這裏參考自穿褲衩闖天下 的文章《Android 守護進程的實現方式》

AndroidLow Memory Killer基於LinuxOOM機制,在Linux中,內存是以頁面爲單位分配的,當申請頁面分配時若是內存不足會經過如下流程選擇bad進程來殺掉從而釋放內存:

alloc_pages -> out_of_memory() -> select_bad_process() -> badness()

Low Memory Killer中經過進程的oom_adj與佔用內存的大小決定要殺死的進程,oom_adj越小越不容易被殺死;
Low Memory Killer Driver在用戶空間指定了一組內存臨界值及與之一一對應的一組oom_adj值,當系統剩餘內存位於內存臨界值中的一個範圍內時,若是一個進程的oom_adj值大於或等於這個臨界值對應的oom_adj值就會被殺掉。

下邊是表示Process State(即老版本里的OOM_ADJ)數值對照表,數值越大,重要性越低,在新版SDK中已經在android層去除了小於0的進程狀態

// Path:SDK/sources/android-25/android/app/ActivityManager#RunningAppProcessInfo.java 
// 進程不存在。 
public static final int PROCESS_STATE_NONEXISTENT = -1;
// 進程是一個持久的系統進程,通常指當前 UI 進程
public static final int PROCESS_STATE_PERSISTENT = 0;
// 進程是一個持久的系統進程,正在作和 UI 相關的操做,但不直接顯示
public static final int PROCESS_STATE_PERSISTENT_UI = 1;
// 進程正在託管當前的頂級活動。請注意,這涵蓋了用戶可見的全部活動。 
public static final int PROCESS_STATE_TOP = 2;
// 進程因爲系統綁定而託管前臺服務。
public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3;
// 進程正在託管前臺服務。
public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
// 與{@link #PROCESS_STATE_TOP}相同,但設備處於睡眠狀態。 
public static final int PROCESS_STATE_TOP_SLEEPING = 5;
// 進程對用戶很重要,是他們知道的東西
public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
// 進程對用戶很重要,但不是他們知道的
public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
// 進程在後臺運行備份/恢復操做
public static final int PROCESS_STATE_BACKUP = 8;
// 進程在後臺,但咱們不能恢復它的狀態,因此咱們想盡可能避免殺死它,否則這個而進程就丟了
public static final int PROCESS_STATE_HEAVY_WEIGHT = 9;
// 進程在後臺運行一個服務,與oom_adj不一樣,此級別用於正常運行在後臺狀態和執行操做狀態。 
public static final int PROCESS_STATE_SERVICE = 10;
// 進程在後臺運行一個接收器,注意,從oom_adj接收器的角度來看,在較高的前臺級運行,可是對於咱們的優先級,這不是必需的,而且將它們置於服務之下意味着當它們接收廣播時,一些進程狀態中的更少的改變。 
public static final int PROCESS_STATE_RECEIVER = 11;
// 進程在後臺,但主持家庭活動
public static final int PROCESS_STATE_HOME = 12;
// 進程在後臺,但託管最後顯示的活動
public static final int PROCESS_STATE_LAST_ACTIVITY = 13;
// 進程正在緩存以供之後使用,幷包含活動
public static final int PROCESS_STATE_CACHED_ACTIVITY = 14;
// 進程正在緩存供之後使用,而且是包含活動的另外一個緩存進程的客戶端
public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 15;
// 進程正在緩存以供之後使用,而且爲空
public static final int PROCESS_STATE_CACHED_EMPTY = 16;

在Android 8.0 中是這樣的,增長了1七、18兩個值四個STATE:PROCESS_STATE_CACHED_EMPTY、PROCESS_STATE_NONEXISTENT、MIN_PROCESS_STATE、MAX_PROCESS_STATE。

    /** @hide Not a real process state. */
    public static final int PROCESS_STATE_UNKNOWN = -1;

    /** @hide Process is a persistent system process. */
    public static final int PROCESS_STATE_PERSISTENT = 0;

    /** @hide Process is a persistent system process and is doing UI. */
    public static final int PROCESS_STATE_PERSISTENT_UI = 1;

    /** @hide Process is hosting the current top activities.  Note that this covers
     * all activities that are visible to the user. */
    public static final int PROCESS_STATE_TOP = 2;

    /** @hide Process is hosting a foreground service due to a system binding. */
    public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3;

    /** @hide Process is hosting a foreground service. */
    public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;

    /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
    public static final int PROCESS_STATE_TOP_SLEEPING = 5;

    /** @hide Process is important to the user, and something they are aware of. */
    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;

    /** @hide Process is important to the user, but not something they are aware of. */
    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;

    /** @hide Process is in the background transient so we will try to keep running. */
    public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8;

    /** @hide Process is in the background running a backup/restore operation. */
    public static final int PROCESS_STATE_BACKUP = 9;

    /** @hide Process is in the background, but it can't restore its state so we want
     * to try to avoid killing it. */
    public static final int PROCESS_STATE_HEAVY_WEIGHT = 10;

    /** @hide Process is in the background running a service.  Unlike oom_adj, this level
     * is used for both the normal running in background state and the executing
     * operations state. */
    public static final int PROCESS_STATE_SERVICE = 11;

    /** @hide Process is in the background running a receiver.   Note that from the
     * perspective of oom_adj receivers run at a higher foreground level, but for our
     * prioritization here that is not necessary and putting them below services means
     * many fewer changes in some process states as they receive broadcasts. */
    public static final int PROCESS_STATE_RECEIVER = 12;

    /** @hide Process is in the background but hosts the home activity. */
    public static final int PROCESS_STATE_HOME = 13;

    /** @hide Process is in the background but hosts the last shown activity. */
    public static final int PROCESS_STATE_LAST_ACTIVITY = 14;

    /** @hide Process is being cached for later use and contains activities. */
    public static final int PROCESS_STATE_CACHED_ACTIVITY = 15;

    /** @hide Process is being cached for later use and is a client of another cached
     * process that contains activities. */
    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 16;

    /** @hide Process is being cached for later use and is empty. */
    public static final int PROCESS_STATE_CACHED_EMPTY = 17;

    /** @hide Process does not exist. */
    public static final int PROCESS_STATE_NONEXISTENT = 18;

    /** @hide The lowest process state number */
    public static final int MIN_PROCESS_STATE = PROCESS_STATE_PERSISTENT;

    /** @hide The highest process state number */
    public static final int MAX_PROCESS_STATE = PROCESS_STATE_NONEXISTENT;

 

Process State(即老版本的OOM_ADJ)與Process Importance對應關係,這個方法也是在ActivityManager.java類中,有了這個關係,就知道能夠知道咱們的應用處於哪一個級別,對於咱們後邊優化有個很好地參考

/** 
 * Path:SDK/sources/android-25/android/app/ActivityManager#RunningAppProcessInfo.java
 * 這裏在Android8.0中沒有發生變化
 * 經過這個方法,將Linux底層的 OOM_ADJ級別碼和 android 層面的進程重要程度聯繫了起來
 */
public static int procStateToImportance(int procState) {
    if (procState == PROCESS_STATE_NONEXISTENT) {
        return IMPORTANCE_GONE;
    } else if (procState >= PROCESS_STATE_HOME) {
        return IMPORTANCE_BACKGROUND;
    } else if (procState >= PROCESS_STATE_SERVICE) {
        return IMPORTANCE_SERVICE;
    } else if (procState > PROCESS_STATE_HEAVY_WEIGHT) {
        return IMPORTANCE_CANT_SAVE_STATE;
    } else if (procState >= PROCESS_STATE_IMPORTANT_BACKGROUND) {
        return IMPORTANCE_PERCEPTIBLE;
    } else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) {
        return IMPORTANCE_VISIBLE;
    } else if (procState >= PROCESS_STATE_TOP_SLEEPING) {
        return IMPORTANCE_TOP_SLEEPING;
    } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) {
        return IMPORTANCE_FOREGROUND_SERVICE;
    } else {
        return IMPORTANCE_FOREGROUND;
    }
}

通常狀況下,設備端進程被幹掉有一下幾種狀況

進程結束場景 結束方式 影響範圍
Android 系統自身內存回收機制 Low Memory Killer Process State 數值從大到小
第三方管理程序清理進程 無 Root 權限 killBackgroundProcess Process State 數值大於6進程
第三方管理程序清理進程 有 Root 權限 force-stop or Kill 除當前前臺進程外全部非系統進程
Rom 清除進程(用戶手動清理) force-stop or Kill 全部非系統進程
用戶手動強制結束 force-stop 第三方應用以及非 System 進程

 

 

 

 

Android進程狀態轉換

這裏參考了一篇CSDN的文章

 

Android應用進程啓動

當咱們在Launcher桌面上點擊一個應用的圖標時,固然Launcher啓動以後,已經把桌面上每一個圖標對應的信息都封裝好了,用戶點擊以後,Launcher進程就會經過Binder進程間通訊機制調用startActivity的方式去打開目標進程的入口Activity,指令傳達到ActivityManagerService當中時,AMS會去檢測當有的應用進程是否已經啓動,若是沒有啓動,那麼就會先將當前的目標進程啓動起來,啓動目標進程是經過調用startProcessLocked方法來完成的。

方法的實如今ActivityManagerService類中,目錄路徑爲frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java,startProcessLocked方法的源碼以下:

private final void startProcessLocked(ProcessRecord app,  
                                      String hostingType, String hostingNameStr) {  
    startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,  
            null /* entryPoint */, null /* entryPointArgs */);  
}  

該方法就是直接調用另外一個重載方法來實如今,該重載方法的源碼以下:

private final void startProcessLocked(ProcessRecord app, String hostingType,  
                                          String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {  
        long startTime = SystemClock.elapsedRealtime();  
        if (app.pid > 0 && app.pid != MY_PID) {  
            checkTime(startTime, "startProcess: removing from pids map");  
            synchronized (mPidsSelfLocked) {  
                mPidsSelfLocked.remove(app.pid);  
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);  
            }  
            checkTime(startTime, "startProcess: done removing from pids map");  
            app.setPid(0);  
        }  
  
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,  
                "startProcessLocked removing on hold: " + app);  
        mProcessesOnHold.remove(app);  
  
        checkTime(startTime, "startProcess: starting to update cpu stats");  
        updateCpuStats();  
        checkTime(startTime, "startProcess: done updating cpu stats");  
  
        try {  
            try {  
                final int userId = UserHandle.getUserId(app.uid);  
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);  
            } catch (RemoteException e) {  
                throw e.rethrowAsRuntimeException();  
            }  
  
            int uid = app.uid;  
            int[] gids = null;  
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;  
            if (!app.isolated) {  
                int[] permGids = null;  
                try {  
                    checkTime(startTime, "startProcess: getting gids from package manager");  
                    final IPackageManager pm = AppGlobals.getPackageManager();  
                    permGids = pm.getPackageGids(app.info.packageName,  
                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);  
                    StorageManagerInternal storageManagerInternal = LocalServices.getService(  
                            StorageManagerInternal.class);  
                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,  
                            app.info.packageName);  
                } catch (RemoteException e) {  
                    throw e.rethrowAsRuntimeException();  
                }  
  
                /* 
                 * Add shared application and profile GIDs so applications can share some 
                 * resources like shared libraries and access user-wide resources 
                 */  
                if (ArrayUtils.isEmpty(permGids)) {  
                    gids = new int[3];  
                } else {  
                    gids = new int[permGids.length + 3];  
                    System.arraycopy(permGids, 0, gids, 3, permGids.length);  
                }  
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));  
                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));  
                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));  
            }  
            checkTime(startTime, "startProcess: building args");  
            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {  
                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL  
                        && mTopComponent != null  
                        && app.processName.equals(mTopComponent.getPackageName())) {  
                    uid = 0;  
                }  
                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL  
                        && (app.info.flags & ApplicationInfo.FLAG_FACTORY_TEST) != 0) {  
                    uid = 0;  
                }  
            }  
            int debugFlags = 0;  
            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {  
                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;  
                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;  
                // Also turn on CheckJNI for debuggable apps. It's quite  
                // awkward to turn on otherwise.  
                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;  
            }  
            // Run the app in safe mode if its manifest requests so or the  
            // system is booted in safe mode.  
            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||  
                    mSafeMode == true) {  
                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;  
            }  
            if ("1".equals(SystemProperties.get("debug.checkjni"))) {  
                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;  
            }  
            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");  
            if ("true".equals(genDebugInfoProperty)) {  
                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;  
            }  
            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {  
                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;  
            }  
            if ("1".equals(SystemProperties.get("debug.assert"))) {  
                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;  
            }  
            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {  
                // Enable all debug flags required by the native debugger.  
                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything  
                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info  
                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations  
                mNativeDebuggingApp = null;  
            }  
  
            String invokeWith = null;  
            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {  
                // Debuggable apps may include a wrapper script with their library directory.  
                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";  
                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();  
                try {  
                    if (new File(wrapperFileName).exists()) {  
                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;  
                    }  
                } finally {  
                    StrictMode.setThreadPolicy(oldPolicy);  
                }  
            }  
  
            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;  
            if (requiredAbi == null) {  
                requiredAbi = Build.SUPPORTED_ABIS[0];  
            }  
  
            String instructionSet = null;  
            if (app.info.primaryCpuAbi != null) {  
                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);  
            }  
  
            app.gids = gids;  
            app.requiredAbi = requiredAbi;  
            app.instructionSet = instructionSet;  
  
            // the per-user SELinux context must be set  
            if (TextUtils.isEmpty(app.info.seInfoUser)) {  
                Slog.wtf(TAG, "SELinux tag not defined",  
                        new IllegalStateException("SELinux tag not defined for "  
                                + app.info.packageName + " (uid " + app.uid + ")"));  
            }  
            final String seInfo = app.info.seInfo  
                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);  
            // Start the process.  It will either succeed and return a result containing  
            // the PID of the new process, or else throw a RuntimeException.  
            boolean isActivityProcess = (entryPoint == null);  
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";  
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +  
                    app.processName);  
            checkTime(startTime, "startProcess: asking zygote to start proc");  
            ProcessStartResult startResult;  
            if (hostingType.equals("webview_service")) {  
                startResult = startWebView(entryPoint,  
                        app.processName, uid, uid, gids, debugFlags, mountExternal,  
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,  
                        app.info.dataDir, null, entryPointArgs);  
            } else {  
                startResult = Process.start(entryPoint,  
                        app.processName, uid, uid, gids, debugFlags, mountExternal,  
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,  
                        app.info.dataDir, invokeWith, entryPointArgs);  
            }  
            checkTime(startTime, "startProcess: returned from zygote!");  
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  
            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);  
            checkTime(startTime, "startProcess: done updating battery stats");  
  
            EventLog.writeEvent(EventLogTags.AM_PROC_START,  
                    UserHandle.getUserId(uid), startResult.pid, uid,  
                    app.processName, hostingType,  
                    hostingNameStr != null ? hostingNameStr : "");  
  
            try {  
                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,  
                        seInfo, app.info.sourceDir, startResult.pid);  
            } catch (RemoteException ex) {  
                // Ignore  
            }  
  
            if (app.persistent) {  
                Watchdog.getInstance().processStarted(app.processName, startResult.pid);  
            }  
  
            checkTime(startTime, "startProcess: building log message");  
            StringBuilder buf = mStringBuilder;  
            buf.setLength(0);  
            buf.append("Start proc ");  
            buf.append(startResult.pid);  
            buf.append(':');  
            buf.append(app.processName);  
            buf.append('/');  
            UserHandle.formatUid(buf, uid);  
            if (!isActivityProcess) {  
                buf.append(" [");  
                buf.append(entryPoint);  
                buf.append("]");  
            }  
            buf.append(" for ");  
            buf.append(hostingType);  
            if (hostingNameStr != null) {  
                buf.append(" ");  
                buf.append(hostingNameStr);  
            }  
            Slog.i(TAG, buf.toString());  
            app.setPid(startResult.pid);  
            app.usingWrapper = startResult.usingWrapper;  
            app.removed = false;  
            app.killed = false;  
            app.killedByAm = false;  
            checkTime(startTime, "startProcess: starting to update pids map");  
            ProcessRecord oldApp;  
            synchronized (mPidsSelfLocked) {  
                oldApp = mPidsSelfLocked.get(startResult.pid);  
            }  
            // If there is already an app occupying that pid that hasn't been cleaned up  
            if (oldApp != null && !app.isolated) {  
                // Clean up anything relating to this pid first  
                Slog.w(TAG, "Reusing pid " + startResult.pid  
                        + " while app is still mapped to it");  
                cleanUpApplicationRecordLocked(oldApp, false, false, -1,  
                        true /*replacingPid*/);  
            }  
            synchronized (mPidsSelfLocked) {  
                this.mPidsSelfLocked.put(startResult.pid, app);  
                if (isActivityProcess) {  
                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);  
                    msg.obj = app;  
                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper  
                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);  
                }  
            }  
            checkTime(startTime, "startProcess: done updating pids map");  
        } catch (RuntimeException e) {  
            Slog.e(TAG, "Failure starting process " + app.processName, e);  
  
            // Something went very wrong while trying to start this process; one  
            // common case is when the package is frozen due to an active  
            // upgrade. To recover, clean up any active bookkeeping related to  
            // starting this process. (We already invoked this method once when  
            // the package was initially frozen through KILL_APPLICATION_MSG, so  
            // it doesn't hurt to use it again.)  
            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,  
                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");  
        }  
    }  

 該方法中int uid = app.uid能夠獲取到目標進程的uid,uid是標識目標進程身份的一個整數,它最原始的分配是在應用進程安裝時,由PackageManagerService分配好

關於Android進程模型

在安裝Android應用程序的時候,Android會爲每一個程序分配一個Linux用戶id,並設置相應的權限,這樣其它應用程序就不能訪問此應用程序所擁有的數據和資源了。

默認狀況下,每一個apk運行在它本身的Linux進程中。當須要執行應用程序中的代碼時,Android會啓動一個jvm,即一個新的進程來執行,所以不一樣的apk運行在相互隔離的環境中。

同時,開發者能夠給兩個應用程序分配相同的linux用戶id,這樣他們就能訪問對方所擁有的資源。爲了保留系統資源,擁有相同用戶id的應用程序能夠運行在同一個進程中,共享同一個jvm。

課堂演示

 

衆所周知,Linux中的全部進程都是有init進程建立並運行的。首先Linux內核啓動,而後在用戶空間中啓動init進程,再啓動其餘系統進程。在系統啓動完成完成後,init將變爲守護進程監視系統其餘進程。Android是基於Linux的操做系統,因此init也是Android系統中用戶空間的第一個進程,它的進程號是1。下面先簡單的看一下init進程的啓動過程。 

 

 

Android 的線程調度

Android 進程生命週期與ADJ

Android 開發者應該都知道在系統中進程重要性的劃分:

 

  • 前臺進程(Foreground process)
  • 可見進程(Visible process)
  • 服務進程(Service process)
  • 後臺進程(Background process)
  • 空進程(Empty process)

相信你們都很清楚,這裏就不作過多的介紹了,不過對於進程重要性是經過哪些操做發生變動的,以及和咱們前面講的 Linux 進程分組又是怎麼關聯和映射上的,是下面要講述的重點。

Android 進程優先級的相關概念

oom_score_adj 級別

對於每個運行中的進程,Linux 內核都經過 proc 文件系統暴露 /proc/[pid]/oom_score_adj這樣一個文件來容許其餘程序修改指定進程的優先級,這個文件容許的值的範圍是:-1000 ~ +1001之間。值越小,表示進程越重要。當內存很是緊張時,系統便會遍歷全部進程,以肯定哪一個進程須要被殺死以回收內存,此時便會讀取 oom_score_adj 這個文件的值。

PS:在Linux 2.6.36以前的版本中,Linux 提供調整優先級的文件是  /proc/[pid]/oom_adj 。這個文件容許的值的範圍是-17 ~ +15之間。數值越小表示進程越重要。 這個文件在新版的 Linux 中已經廢棄。但你仍然可使用這個文件,當你修改這個文件的時候,內核會直接進行換算,將結果反映到  oom_score_adj 這個文件上。 

Android早期版本的實現中也是依賴  oom_adj 這個文件。可是在新版本中,已經切換到使用  oom_score_adj 這個文件。

爲了便於管理,ProcessList.java中預約義了 oom_score_adj 的可能取值,這裏的預約義值也是對應用進程的一種分類。

 

 

Lowmemorykiller 根據當前可用內存狀況來進行進程釋放,總設計了6個級別,即上表中「解釋列」加粗的行,即 Lowmemorykiller 的殺進程的6檔,以下:

 

  • CACHED_APP_MAX_ADJ
  • CACHED_APP_MIN_ADJ
  • BACKUP_APP_ADJ
  • PERCEPTIBLE_APP_ADJ
  • VISIBLE_APP_ADJ
  • FOREGROUND_APP_ADJ

系統內存從很寬裕到不足,Lowmemorykiller 也會相應地從 CACHED_APP_MAX_ADJ (第1檔)開始殺進程,若是內存還不足,那麼會殺 CACHED_APP_MIN_ADJ (第2檔),不斷深刻,直到知足內存閾值條件。

ProcessRecord中下面這些屬性反應了 oom_score_adj 的值:

int maxAdj; // Maximum OOM adjustment for this process int curRawAdj; // Current OOM unlimited adjustment for this process int setRawAdj; // Last set OOM unlimited adjustment for this process int curAdj; // Current OOM adjustment for this process int setAdj; // Last set OOM adjustment for this process int verifiedAdj; // The last adjustment that was verified as actually being set 

Process State

對應的在 ActivityManager 重定義了 process_state 級別的劃分,Android 系統會在修改進程狀態的同時更新 oom_score_adj 的分級:

 

 

在 ProcessRecord 中,記錄了和進程狀態相關的屬性:

int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for 

Schedule Group

對應到底層進程分組,除了上面提到的 Process.java 定義的不一樣線程組的定義,同時還爲 Activity manager 定義了一套相似的調度分組,和以前的線程分組定義也存在對應關係:

// Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE static final int SCHED_GROUP_BACKGROUND = 0; // Activity manager's version of Process.THREAD_GROUP_DEFAULT static final int SCHED_GROUP_DEFAULT = 1; // Activity manager's version of Process.THREAD_GROUP_TOP_APP static final int SCHED_GROUP_TOP_APP = 2; // Activity manager's version of Process.THREAD_GROUP_TOP_APP // Disambiguate between actual top app and processes bound to the top app static final int SCHED_GROUP_TOP_APP_BOUND = 3; 

在 ProcessRecord 中,也記錄了和調度組相關的屬性:

int curSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class 

Android 進程優先級的變化

咱們知道影響 Android 應用進程優先級變化的是根據 Android 
應用組件的生命週期變化相關。Android進程調度之adj算法 裏面羅列了全部會觸發進程狀態發生變化的事件,主要包括:

Actvity

 

  • ActivityStackSupervisor.realStartActivityLocked: 啓動Activity
  • ActivityStack.resumeTopActivityInnerLocked: 恢復棧頂Activity
  • ActivityStack.finishCurrentActivityLocked: 結束當前Activity
  • ActivityStack.destroyActivityLocked: 摧毀當前Activity

Service

位於ActiveServices.java

 

  • realStartServiceLocked: 啓動服務
  • bindServiceLocked: 綁定服務(只更新當前app)
  • unbindServiceLocked: 解綁服務 (只更新當前app)
  • bringDownServiceLocked: 結束服務 (只更新當前app)
  • sendServiceArgsLocked: 在bringup或則cleanup服務過程調用 (只更新當前app)

broadcast

 

  • BQ.processNextBroadcast: 處理下一個廣播
  • BQ.processCurBroadcastLocked: 處理當前廣播
  • BQ.deliverToRegisteredReceiverLocked: 分發已註冊的廣播 (只更新當前app)

ContentProvider

 

  • AMS.removeContentProvider: 移除provider
  • AMS.publishContentProviders: 發佈provider (只更新當前app)
  • AMS.getContentProviderImpl: 獲取provider (只更新當前app)

Process

位於 ActivityManagerService.java

 

  • setSystemProcess: 建立並設置系統進程
  • addAppLocked: 建立persistent進程
  • attachApplicationLocked: 進程建立後attach到system_server的過程;
  • trimApplications: 清除沒有使用app
  • appDiedLocked: 進程死亡
  • killAllBackgroundProcesses: 殺死全部後臺進程.即(ADJ>9或removed=true的普通進程)
  • killPackageProcessesLocked: 以包名的形式 殺掉相關進程;

這些事件都會直接或間接調用到 ActivityManagerService.java 中的 updateOomAdjLocked 方法來更新進程的優先級,updateOomAdjLocked 先經過 computeOomAdjLocked 方法負責計算進程的優先級,再經過調用 applyOomAdjLocked 應用進程的優先級。

computeOomAdjLocked

computeOomAdjLocked 方法負責計算進程的優先級,總計約700行,執行流程比較清晰,步驟以下,因爲代碼有點多這裏就不貼了,想仔細研究的能夠比着系統源碼看:

相關文章
相關標籤/搜索