<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                前面介紹了Linux OS中進程管理(包括調度和OOM控制)方面的API,但AMS是如何利用它們的呢?這就涉及AMS中的進程管理規則了。這里簡單介紹相關規則。 Android將應用進程分為五大類,分別為Forground類、Visible類、Service類、Background類及Empty類。這五大類的劃分各有規則。 1. 進程分類 (1) Forground類 該類中的進程重要性最高,屬于該類的進程包括下面幾種情況: - 含一個前端Activity(即onResume函數被調用過了,或者說當前正在顯示的那個Activity)。 - 含一個Service,并且該Service和一個前端Activity綁定(例如Music應用包括一個前端界面和一個播放Service,當我們一邊聽歌一邊操作Music界面時,該Service即和一個前端Activity綁定)。 - 含一個調用了startForground的Service,或者該進程的Service正在調用其生命周期的函數(onCreate、onStart或onDestroy)。 - 最后一種情況是,該進程中有BroadcastReceiver實例正在執行onReceive函數。 (2) Visible類 屬于Visible類的進程中沒有處于前端的組件,但是用戶仍然能看到它們,例如位于一個對話框后的Activity界面。目前該類進程包括兩種: - 該進程包含一個僅onPause被調用的Activity(即它還在前臺,只不過部分界面被遮住)。 - 或者包含一個Service,并且該Service和一個Visible(或Forground)的Activity綁定(從字面意義上看,這種情況不太好和Forground進程中第二種情況區分)。 (3) Service類、Background類及Empty類 這三類進程都沒有可見的部分,具體情況如下。 - Service進程:該類進程包含一個Service。此Service通過startService啟動,并且不屬于前面兩類進程。這種進程一般在后臺默默地干活,例如前面介紹的MediaScannerService。 - Background進程:該類進程包含當前不可見的Activity(即它們的onStop被調用過)。系統保存這些進程到一個LRU(最近最少使用)列表。當系統需要回收內存時,該列表中那些最近最少使用的進程將被殺死。 - Empty進程:這類進程中不包含任何組件。為什么會出現這種不包括任何組件的進程呢?其實很簡單,假設該進程僅創建了一個Activity,它完成工作后主動調用finish函數銷毀(destroy)自己,之后該進程就會成為Empty進程。系統保留Empty進程的原因是當又重新需要它們時(例如用戶在別的進程中通過startActivity啟動了它們),可以省去fork進程、創建Android運行環境等一系列漫長而艱苦的工作。 通過以上介紹可發現,當某個進程和前端顯示有關系時,其重要性相對要高,這或許是體現Google重視用戶體驗的一個很直接的證據吧。 * * * * * **建議**:讀者可閱讀SDK/docs/guide/topics/fundamentals/processes-and-threads.html以獲取更為詳細的信息。 * * * * * 2. Process類API介紹 我們先來介紹Android平臺中進程調度和OOM控制的API,它們統一被封裝在Process.java中,其相關代碼如下: **Process.java** ~~~ //設置線程的調度優先級,Linux kernel并不區分線程和進程,二者對應同一個數據結構Task public static final native void setThreadPriority(inttid, int priority) throws IllegalArgumentException, SecurityException; /* 設置線程的Group,實際上就是設置線程的調度策略,目前Android定義了三種Group。 由于缺乏相關資料,加之筆者感覺對應的注釋也只可意會不可言傳,故此處直接照搬了英文 注釋,敬請讀者諒解。 THREAD_GROUP_DEFAULT:Default thread group - gets a 'normal'share of the CPU THREAD_GROUP_BG_NONINTERACTIVE:Background non-interactive thread group. Allthreads in this group are scheduled with a reduced share of the CPU THREAD_GROUP_FG_BOOST:Foreground 'boost' thread group - Allthreads in this group are scheduled with an increasedshare of the CPU. 目前代碼中還沒有地方使用THREAD_GROUP_FG_BOOST這種Group */ public static final native void setThreadGroup(inttid, int group) throws IllegalArgumentException, SecurityException; //設置進程的調度策略,包括該進程的所有線程 public static final native voidsetProcessGroup(int pid, int group) throws IllegalArgumentException, SecurityException; //設置線程的調度優先級 public static final native voidsetThreadPriority(int priority) throws IllegalArgumentException, SecurityException; //調整進程的oom_adj值 public static final native boolean setOomAdj(intpid, int amt); ~~~ Process類還為不同調度優先級定義一些非常直觀的名字以避免在代碼中直接使用整型,例如為最低的調度優先級19定義了整型變量THREAD_PRIORITY_LOWEST。除此之外,Process還提供了fork子進程等相關的函數。 * * * * * **注意**:Process.java中的大多數函數是由JNI層實現的,其中Android在調度策略設置這一功能上還有一些特殊的地方,感興趣的讀者不妨閱讀system/core/libcutils/sched_policy.c文件。 * * * * * 3. 關于ProcessList類和ProcessRecord類的介紹 (1) ProcessList類的介紹 ProcessList類有兩個主要功能: - 定義一些成員變量,這些成員變量描述了不同狀態下進程的oom_adj值。 - 在Android 4.0之后,LMK的配置參數由ProcessList綜合考慮手機總內存大小和屏幕尺寸后再行設置(在Android 2.3中,LMK的配置參數在init.rc中由init進程設置,并且沒有考慮屏幕尺寸的影響)。讀者可自行閱讀其updateOomLevels函數,此處不再贅述。 本節主要關注ProcessList對oom_adj的定義。雖然前面介紹時將Android進程分為五大類,但是在實際代碼中的劃分更為細致,考慮得更為周全。 **ProcessList.java** ~~~ class ProcessList { //當一個進程連續發生Crash的間隔小于60秒時,系統認為它是為Bad進程 staticfinal int MIN_CRASH_INTERVAL = 60*1000; //下面定義各種狀態下進程的oom_adj //不可見進程的oom_adj,最大15,最小為7。殺死這些進程一般不會帶來用戶能夠察覺的影響 staticfinal int HIDDEN_APP_MAX_ADJ = 15; staticint HIDDEN_APP_MIN_ADJ = 7; /* 位于B List中Service所在進程的oom_adj。什么樣的Service會在BList中呢?其中的 解釋只能用原文來表達” these are the old anddecrepit services that aren't as shiny andinteresting as the ones in the A list“ */ staticfinal int SERVICE_B_ADJ = 8; /* 前一個進程的oom_adj,例如從A進程的Activity跳轉到位于B進程的Activity, B進程是當前進程,而A進程就是previous進程了。因為從當前進程A退回B進程是一個很簡單 卻很頻繁的操作(例如按back鍵退回上一個Activity),所以previous進程的oom_adj 需要單獨控制。這里不能簡單按照五大類來劃分previous進程,還需要綜合考慮 */ staticfinal int PREVIOUS_APP_ADJ = 7; //Home進程的oom_adj為6,用戶經常和Home進程交互,故它的oom_adj也需要單獨控制 staticfinal int HOME_APP_ADJ = 6; //Service類中進程的oom_adj為5 staticfinal int SERVICE_ADJ = 5; //正在執行backup操作的進程,其oom_adj為4 staticfinal int BACKUP_APP_ADJ = 4; //heavyweight的概念前面曽提到過,該類進程的oom_adj為3 staticfinal int HEAVY_WEIGHT_APP_ADJ = 3; //Perceptible進程指那些當前并不在前端顯示而用戶能感覺到它在運行的進程,例如正在 //后臺播放音樂的Music staticfinal int PERCEPTIBLE_APP_ADJ = 2; //Visible類進程,oom_adj為1 staticfinal int VISIBLE_APP_ADJ = 1; //Forground類進程,oom_adj為0 staticfinal int FOREGROUND_APP_ADJ = 0; //persistent類進程(即退出后,系統需要重新啟動的重要進程),其oom_adj為-12 staticfinal int PERSISTENT_PROC_ADJ = -12; //核心服務所在進程,oom_adj為-12 staticfinal int CORE_SERVER_ADJ = -12; //系統進程,其oom_adj為-16 staticfinal int SYSTEM_ADJ = -16; //內存頁大小定義為4KB staticfinal int PAGE_SIZE = 4*1024; //系統中能容納的不可見進程數最少為2,最多為15。在Android 4.0系統中,可通過設置程序來 //調整 staticfinal int MIN_HIDDEN_APPS = 2; staticfinal int MAX_HIDDEN_APPS = 15; //下面兩個參數用于調整進程的LRU權重。注意,它們的注釋和具體代碼中的用法不能統一起來 staticfinal long CONTENT_APP_IDLE_OFFSET = 15*1000; staticfinal long EMPTY_APP_IDLE_OFFSET = 120*1000; //LMK設置了6個oom_adj閾值 privatefinal int[] mOomAdj = new int[] { FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, EMPTY_APP_ADJ }; //用于內存較低機器(例如小于512MB)中LMK的內存閾值配置 privatefinal long[] mOomMinFreeLow = new long[] { 8192, 12288, 16384, 24576, 28672, 32768 }; //用于較高內存機器(例如大于1GB)的LMK內存閾值配置 privatefinal long[] mOomMinFreeHigh = new long[] { 32768, 40960, 49152, 57344, 65536, 81920 }; ~~~ 從以上代碼中定義的各種ADJ值可知,AMS中的進程管理規則遠比想象得要復雜(讀者以后見識到具體的代碼,更會有這樣的體會)。 * * * * * **說明**:在ProcessList中定義的大部分變量在Android 2.3代碼中定義于ActivityManagerService.java中,但這段代碼的開發者僅把代碼復制了過來,其中的注釋并未隨著系統升級而更新。 * * * * * (2) ProcessRecord中相關成員變量的介紹 ProcessRecord定義了較多成員變量用于進程管理。筆者不打算深究其中的細節。這里僅把其中的主要變量及一些注釋列舉出來。下文會分析到它們的作用。 **ProcessRecord.java** ~~~ //用于LRU列表控制 long lastActivityTime; // For managing the LRU list long lruWeight; // Weight for ordering in LRU list //和oom_adj有關 int maxAdj; // Maximum OOM adjustment for thisprocess int hiddenAdj; // If hidden, this is the adjustment touse int curRawAdj; // Current OOM unlimited adjustment forthis process int setRawAdj; // Last set OOM unlimited adjustment forthis process int curAdj; // Current OOM adjustment for thisprocess int setAdj; // Last set OOM adjustment for thisprocess //和調度優先級有關 int curSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class //回收內存級別,見后文解釋 int trimMemoryLevel; // Last selected memorytrimming level //判斷該進程的狀態,主要和其中運行的Activity,Service有關 boolean keeping; // Actively running code sodon't kill due to that? boolean setIsForeground; // Running foreground UI when last set? boolean foregroundServices; // Running anyservices that are foreground? boolean foregroundActivities; // Running anyactivities that are foreground? boolean systemNoUi; // This is a system process, but notcurrently showing UI. boolean hasShownUi; // Has UI been shown in this process since itwas started? boolean pendingUiClean; // Want to clean up resources from showingUI? boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so wantto be lower //是否處于系統BadProcess列表 boolean bad; // True if disabled in the badprocess list //描述該進程因為是否有太多后臺組件而被殺死 boolean killedBackground; // True when proc has been killed due to toomany bg String waitingToKill; // Process is waiting to be killed whenin the bg; reason //序號,每次調節進程優先級或者LRU列表位置時,這些序號都會遞增 int adjSeq; // Sequence id for identifyingoom_adj assignment cycles int lruSeq; // Sequence id for identifyingLRU update cycles ~~~ 上面注釋中提到了LRU(最近最少使用)一詞,它和AMS另外一個用于管理應用進程ProcessRecord的數據結構有關。 * * * * * **提示**:進程管理和調度一向比較復雜,從ProcessRecord定義的這些變量中可見一斑。需要提醒讀者的是,對這部分功能的相關說明非常少,代碼讀起來會感覺比較晦澀。 * * * * *
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看