日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

[Android]你不知道的Android进程化(3)--进程等级

發布時間:2025/3/15 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Android]你不知道的Android进程化(3)--进程等级 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們可以看到現在Android的運行內存越來越大,6G、8G的大內存時代,越大運存將允許運行越多的app,而Android系統也組建增大進程可以申請的最大運存量。Android 系統將盡量長時間地保持應用進程,內存是有限的,為了新建進程或運行更重要的進程,最終需要移除舊進程來回收內存。
為了確定哪些進程是能夠被移除的,Android系統引用了進程優先級別的機制。Android進程的優先層級結構一共分5層。

1.前臺進程:(foreground process)

用戶當前操作所必需的進程。如果一個進程滿足以下任一條件,即視為前臺進程:
(1)用戶正在交互使用的 Activity(已調用 Activity 的 onResume() 方法)
(2)某個 Service,后者綁定到用戶正在交互的 Activity。
(3)正在“前臺”運行的 Service(服務已調用 startForeground())
(4)正執行一個生命周期回調的 Service(onCreate()、onStart() 或 onDestroy())
(5)正執行其 onReceive() 方法的 BroadcastReceiver
通常,在任意給定時間前臺進程都為數不多。只有在內存不足以支持它們同時繼續運行這一萬不得已的情況下,系統才會終止它們。 此時,設備往往已達到內存分頁狀態,因此需要終止一些前臺進程來確保用戶界面正常響應。

2.可見進程:

沒有任何前臺組件、但仍會影響用戶在屏幕上所見內容的進程。 如果一個進程滿足以下任一條件,即視為可見進程:
(1)不在前臺、但仍對用戶可見的 Activity(已調用其 onPause() 方法)。例如,如果前臺 Activity 啟動了一個對話框,允許在其后顯示上一 Activity,則有可能會發生這種情況。
(2)綁定到可見(或前臺)Activity 的 Service。 (不包含startForground()的情況)
可見進程被視為是極其重要的進程,除非為了維持所有前臺進程同時運行而必須終止,否則系統不會終止這些進程。

3.服務進程

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

4.后臺進程:

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

5.空進程

不含任何活動應用組件的進程。保留這種進程的的唯一目的是用作緩存,以縮短下次在其中運行組件所需的啟動時間。 為使總體系統資源在進程緩存和底層內核緩存之間保持平衡,系統往往會終止這些進程。
根據進程中當前活動組件的重要程度,Android 會將進程評定為它可能達到的最高級別。例如,如果某進程托管著服務和可見 Activity,則會將此進程評定為可見進程,而不是服務進程。

連接adb命令,使用dumpsys meminfo命令時,會列出當前系統的所有進程,不同進程放入不同的分類。

Linux API:
Linux提供了兩個API用于設置調度優先級及調度策略。

  • 設置調度優先級的API為:
  • int setpriority(int which, int who, int prio)

    其中,which和who聯合使用。

    當which為PRIO_PROGRESS時,who代表一個進程,即pid;
    當which為PRIO_PGROUP時,who代表一個進程組,即gid;
    當which為PRIO_USER時,who代表一個用戶,即uid。

    prio用于設置進程的nice值,取值范圍為-20~+19。
    該值越大表示進程越友好(nice),即對CPU資源的依賴越低。
    于是,進程的prio值越大,其被調用的優先級越低。

  • 設置調度策略的API為:
  • int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);

    其中,pid表示進程id。

    policy表示調度策略。
    Linux定義了很多種調度策略,具體的內容可以參考相關的資料。

    param參數中,最重要的是該結構體中的sched_priority變量。
    該變量用于設置該調度策略下,進程的優先級。

    以上只是簡單的進程級別分類,如果按照lowmeorykiller中進程的分類將會更為完整一點。
    每一類別的進程會有其oom_adj值的取值范圍,oom_adj值越高則代表進程越不重要,在系統執行低內存殺進程操作時,會從oom_adj值越高的開始殺。
    ProcessList中記錄了進程的等級判斷

    系統級別的進程都是使用負數的進程級別,所以不會被判定回收


    系統級別進程

    oom_adj是每進程的進程級別。
    如何查看某個應用的oom_adj數值?
    首先adb shell#ps查看應用的PID。
    然后#cat /proc/PID/oom_adj的結果就是。

    應用級別進程等級.png

    此源碼是android 7.1.1源碼,可能舊的源碼等級數字會小一點。
    前臺進程 oom_adj 0
    可見進程 oom_adj 100
    可感知進程 oom_adj 200
    后臺進程 oom_adj 300
    后臺重量級進程 oom_adj 400
    服務進程 oom_adj 500
    Home進程 oom_adj 600
    前一個進程 oom_adj 700
    服務進程 oom_adj 800
    緩存進程 oom_adj 900~906

    其職能和舊版本的Android并沒不同,可以借鑒# 溪亭瀝酒的下圖

    舊版Android的oom_adj等級.png

    當需要釋放內存,運行新的app的時候,進程oom_adj數值越高,進程就越容易被lowmemroykiller殺死回收。

    在ActivityManager當中又自有一套進程分級,而且更加詳細的級別,和ProcessList中的某些等級是對應的,可以從ProcessList中看出。(圖中等級并不是全部等級)

    屏幕快照 2018-01-14 下午9.16.38.png

    AMS內部就是使用這份進程等級記錄。
    內存管理進程是以一種類似Lru模型來做的。

    了解進程等級,對以后進程保活,進程調度有更加深刻的認識。
    剛開始都是說一些比較基礎的進程知識,之后會有更加深入的章節,介紹進程管理的相關源碼。

    本節就到這里。



    作者:CangWang
    鏈接:https://www.jianshu.com/p/a525932db11c
    來源:簡書
    著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

    總結

    以上是生活随笔為你收集整理的[Android]你不知道的Android进程化(3)--进程等级的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。