android 可用記憶體的閥值–轉載

來源:互聯網
上載者:User

Android採取了一種有別於Linux的進程管理原則,有別於Linux的在進程活動停止後就結束該進程,Android把這些進程都保留在記憶體中, 直到系統需要更多記憶體為止。這些保留在記憶體中的進程通常情況下不會影響整體系統的運行速度,並且當使用者再次啟用這些進程時,提升了進程的啟動速度。

那Android什麼時候結束進程?結束哪個進程呢?之前普遍的認識是Android是依據一個名為LRU(last recently used 最近使用過的程式)列表,將程式進行排序,並結束最早的進程。XDA的樓主又進一步對這個管理機制進行研究,有了如下發現:

1.系統會對進程的重要性進行評估,並將重要性以“oom_adj”這個數值表示出來,賦予各個進程;(系統會根據“oom_adj”來判斷需要結束哪些進程,一般來說,“oom_adj”的值越大,該進程被系統選中終止的可能就越高)

2.前景程式的“oom_adj”值為0,這意味著它不會被系統終止,一旦它不可訪問後,會獲得個更高的“oom_adj”,作者推測“oom_adj”的值是根據軟體在LRU列表中的位置所決定的;

3.Android不同於Linux,有一套自己獨特的進程管理模組,這個模組有更強的可定製性,可根據“oom_adj”值的範圍來決定進程管理原則,比如可以設定“當記憶體小於X時,結束“oom_adj”大於Y的進程”。這給了進程管理指令碼的編寫以更多的選擇。

4.Android將進程分為六大類:

1.前台進程(foreground):目前正在螢幕上顯示的進程和一些系統進程。舉例來說,Dialer Storage,Google Search等系統進程就是前台進程;再舉例來說,當你運行一個程式,如瀏覽器,當瀏覽器介面在前台顯示時,瀏覽器屬於前台進程 (foreground),但一旦你按home回到主介面,瀏覽器就變成了背景程式(background)。我們最不希望終止的進程就是前台進程。

2.可見進程(visible):可見進程是一些不再前台,但使用者依然可見的進程,舉個例來說:widget、IME 等,都屬於visible。這部分進程雖然不在前台,但與我們的使用也密切相關,我們也不希望它們被終止(你肯定不希望時鐘、天氣,新聞等widget被 終止,那它們將無法同步,你也不希望IME被終止,否則你每次輸入時都需要重新啟動IME)

3.次要服務(secondary server):目前正在啟動並執行一些服務(主要服務,如撥號等,是不可能被進程管 理終止的,故這裡只談次要服務),舉例來說:Google企業套件,Gmail內部儲存,連絡人內部儲存等。這部分服務雖然屬於次要服務,但很一些系統功能依然息 息相關,我們時常需要用到它們,所以也太希望他們被終止

4.後台進程(hidden):雖然作者用了hidden這個詞,但實際即是後台進程(background),就是 我們通常意義上理解的啟動後被切換到背景進程,如瀏覽器,閱讀器等。當程式顯示在螢幕上時,他所啟動並執行進程即為前台進程(foreground),一旦 我們按home返回主介面(注意是按home,不是按back),程式就駐留在後台,成為後台進程
(background)。後台進程的管理原則有多種:有較為積極的方式,一旦程式到達後台立即終止,這種方式會提高程式的運行速度,但無法加速程式的再 次啟動;也有較消極的方式,儘可能多的保留背景程式,雖然可能會影響到單個程式的運行速度,但在再次啟動已啟動的程式時,速度會有所提升。這裡就需要使用者 根據自己的使用習慣找到一個平衡點

5.內容供應節點(content provider):沒有程式實體,進提供內容供別的程式去用的,比如日曆供應節點,郵件供應節點等。在終止進程時,這類程式應該有較高的優先權

6.空進程(empty):沒有任何東西在內啟動並執行進程,有些程式,比如BTE,在程式退出後,依然會在進程中駐留一個空進程,這個進程裡沒有任何資料在運行,作用往往是提高該程式下次的啟動速度或者記錄程式的一些曆史資訊。這部分進程無疑是應該最先終止的。

實踐

說完理論,說些實踐的東西,怎樣管理這六類進程,如何來設定進程管理模組是這部分說的內容。

首先是軟體,推薦使用MinFreeManager,市場上就有下載,用於設定這六類進程的管理原則。

軟體運行後有六個輸入框,在輸入框中只能輸入數字,這些數字代表了這類進程的處理策略,比如Foreground App下的輸入框顯示6,就表示,當可用記憶體低於6MB時,終止Foreground App。下面的類似,如Empty App下的輸入框顯示24,則表示,當記憶體低於24MB時,終止Empty App。

從軟體數值的設定不難看出結束進程的有限順序:Empty>Content Provider>Hidden>Secondary Server>Visible>Foreground。

但預設設定確存在一些問題:
各類進程的管理原則的閥值相當接近:6,8,16,20,22,24,最大的相差也不到8MB,在實際程式運行中,很容易導致多種類型的進程同時被關閉。 如可用記憶體在25時,突然啟動照相程式,系統可用記憶體急速,可能會導致空進程、內容供應節點、後台進程、次要服務等同時被關閉
閥值上限較低:一般手機啟動後,可用記憶體在50-100左右,但隨著手機的使用,可用記憶體會逐步減少,最後降低到24MB左右,則系統開始啟動進程管理機 制,開始結束進程,但這個閥限制設在了24MB,相對來說偏低。其結果會導致系統使用一段時間後,整體速度變慢。很明顯的就是,當手機長時間使用後,開啟 電話撥號,相簿,照相機等應用時,系統的反應速度極慢。

基於以上幾個問題,不難看出,我們修改的目標也將非常明確,主要解決兩個矛盾:
拉開各進程的閥值層次,使得進程管理機制能更有效得工作
提升閥值上限,空出更多的空餘記憶體,以提升系統整體的運行速度

進程管理原則設定原則:
前台進程、可見進程和次要服務是與使用者體驗息息相關的內容,這部分的進程管理原則要相對保守,給這些進程留下足夠的Runspace
壓榨無用進程,騰出記憶體空間給主要程式使用

下面筆者總結了幾種設定方式,適應不同的使用需要:
遊戲玩家/重度瀏覽器使用者配置:
使用者特點:長時間專註於某一特定的,高記憶體需求的程式,對多任務的需求不高

配置參數:

1.Foreground:6
2.Visible:8
3.Secondary Server:16
4.Hiden App:80
5.Content Provider:90
6.Empty:100

配置理念:壓榨後台進程,內容供應節點和空進程,將記憶體儘可能多得留給前台進程和系統,提升遊戲速度和瀏覽器體驗
優點:程式啟動和啟動並執行速度最快
缺點:多任務處理不理想,開啟程式較多時,後台進程會被終止

多任務配置:
使用者特點:同時運行多個應用程式,需要經常在多個程式間切換

配置參數:

1.Foreground:6
2.Visible:8
3.Secondary Server:16
4.Hiden App:20
5.Content Provider:60
6.Empty:100

配置理念:壓榨空進程,給內容供應節點留有一定空間,最大限度提升背景程式的使用空間,提升多任務的處理能力
優點:運行多個程式時,由於可支配記憶體較多,背景程式不容易被終止
缺點:程式啟動的速度和整體系統的運行速度可能會比遊戲玩家配置略慢一些,由於經常運行多任務,平時系統的響應速度會受到一定影響
輕度使用者/女生專用配置
使用者特點:手機的主要功能是簡訊和電話,偶爾用用相機自拍

配置參數:

1.Foreground:6
2.Visible:8
3.Secondary Server:16
4.Hiden App:24
5.Content Provider:32
6.Empty:48

配置理念:壓榨空進程,給內容供應節點留有一定空間,最大限度提升背景程式的使用空間,提升多任務的處理能力
優點:比較均衡的配置,提升了系統的可用記憶體,使得系統的整體速度得到了提高,拉開了各級進程的管理原則層次,使得管理機制更有效率
缺點:比較均衡的配置,無明顯缺點
總結

闡述完了記憶體管理的機制,並推薦了一些配置參數,但這些參數並不一定適用於所有人,大家也可以根據自己實際的使用習慣調整這些參數的設定。

============================================================================================================我們一直聽說Android是一個多進程作業系統,那麼它是如何處理每一個進程呢? 
大家可能已經發現 Android自身並沒有所謂的關閉進程的說法 每當我們要退出一個進程回到案頭/開啟另一個程式的時候我們只能按"返回鍵". 而當我們按下"返回鍵"後,該進程並沒有真正的關閉,仍然儲存在記憶體中. 這樣在下次調用的時候可以更快的開啟該程式.}

要想真正的關閉一個已開啟的進程,除了用第三方軟體(例如advanced task manager)外,還有一個,那就是當Android系統認為當時已經沒有足夠的記憶體來運行新的進程,需要關閉一些雖然已經開著,但是沒有用了(具體怎 樣一個進程才會被Android系統認為是"沒有用"下面就要討論到)的進程.

而下面要研究的就是這個Android內部的lowmemorykiller.

ActivityManagerService.java記錄著每一個進程的優先順序. 一個進程的oom_adj值也就代表了它的優先順序. oom_adj值越高代表該進程優先順序越低. 一個正在使用的進程的oom_adj值為0,一旦我們按下返回鍵,這個進程就會得到一個更高的oom_adj值(更低的優先順序). 具體多少取決於該進程在LRU(last recently used) list的位置.(未證實)
具體的細節儲存在Android源檔案drivers/misc/lowmemorykiller.c裡.

Android將進程分為6個等級,它們按優先順序順序由高到低依次是:

    1. FOREGROUND_APP:
    This is the process running the current foreground app.  We'd really rather not kill it!
    使用者正在使用的程式. 這個設的太高,使用者看到得就會是一個正在使用的程式莫名其妙的消失了,然後自動回到案頭..(因為它被系統kill了..) 所以最好別動它..

    2. VISIBLE_APP:
    This is a process only hosting activities that are visible to the user, so we'd prefer they don't disappear.8 b2 ]  ]; p5 N; S
    跟FOREGROUND_APP類似,使用者正在使用/看得到. 它們的區別就是VISIBLE_APP可能不是使用者focus的程式,但是使用者看得到,或者沒有覆蓋到整個螢幕,只有螢幕的一部分. 所以可以適當的比FOREGROUND_APP高一點.

    3. SECONDARY_SERVER:
    This is a process holding a secondary server -- killing it will not have much of an impact as far as the user is concerned.
    所有應用的service. 系統級的service比如PhoneService不屬於這類,它們是絕不會被Android結束掉的. 所以這個可以適當的設高一點點~ 注意, HOME(SenseUI)也包括在這裡 因此還是別設的太高. 要不每次返回案頭都得等它重新load,特別是widget多的.

    4. HIDDEN_APP:
    This is a process only hosting activities that are not visible, so it can be killed without any disruption.
    本來屬於1或者2的程式, 在使用者按了"back"或者"home"後,程式本身看不到了,但是其實還在啟動並執行程式,它們就屬於HIDDEN_APP了. 幹掉沒什麼影響.. 不過要瞭解並不是所有屬於這一類的就應該馬上結束掉,像push mail,locale,鬧鐘,等都屬於這一類. 因此還是別設的過高. 真正"應該"一點返回鍵就退出的程式(真正沒用的程式)在下面.

    5. CONTENT_PROVIDER:
    This is a process with a content provider that does not have any clients attached to it.  If it did have any clients, its adjustment would be the one for the highest-priority of those processes.
    5,6的區別具體不太瞭解..這個也是用處不大,但是還是比EMPTY_APP稍微有點用.. 所以高點沒關係~

    6. EMPTY_APP:
    This is a process without anything currently running in it.  Definitely the first to go! This value is initalized in the constructor, careful when refering to this static variable externally.
完全沒用的一個,殺了它只有好處沒壞處,第一個幹它

查看現在的設定可以:
1. # cat /sys/module/lowmemorykiller/parameters/minfree

複製代碼'
顯示出的應該是6個數字,以逗號隔開,例如:
1536,2048,4096,5120,5632,6144

注意這些數位單位是page. 1 page = 4 kilobyte.;
上面的六個數字對應的就是(MB): 6,8,16,20,22,24

這些數字也就是對應的記憶體閥值,一旦低於該值,Android便開始按順序關閉進程. 因此Android開始結束優先順序最低的EMPTY_APP當可用記憶體小於24MB(6144*4/1024).
有一點沒搞明白,它的可用記憶體不知道是從哪得到.. 明顯不是free顯示的可用記憶體,而且貌似compcache跟swap也不影響..

要想重新設定該值:

   1. # echo "1536,2048,4096,5120,15360,23040" > /sys/module/lowmemorykiller/parameters/minfree

複製代碼
這樣當可用記憶體低於90MB的時候便開始結束EMPTY_APP. 而當可用記憶體低於60MB的時候才開始結束CONTENT_PROVIDER組. 其餘四個沒動.

注意:
通過以上方法改變的數值並非永久.在下次重啟後就又恢複到之前的設定. 若想讓設定在每次開機執行,將"
1. echo "1536,3072,4096,21000,23000,25000" > /sys/module/lowmemorykiller/parameters/minfree

複製代碼
加入到任意一個開機啟動的設定檔. 一般在/system/init.d下的檔案都是開機執行的(有的ROM也可能不在這裡..) 只需用記事本開啟任意一個檔案,再把這行加入其中就好.

原作者做了一個應用,在market裡免費,讓大家更改設定更方便,叫 "MinFreeManager".

上面給出的數字只供參考,具體多少才是最優組合正在研究中..

也許大家還不明白這樣做的好處. 這樣的好處就是讓我們隨時有足夠的記憶體來執行我們要啟動並執行程式,而那些真正沒用的進程又不會多餘的佔用著寶貴的記憶體. 更重要的是這一切都是不需要您的參與或任何第三方軟體的協助,完全由Android在後台自動執行. 試想,又有誰會比Android更熟悉的掌握每個進程呢 比起那些記憶體管理程式傻傻的一鍋端的方法聰明多了吧~ 讓我們從現在開始把那些記憶體管理程式刪掉吧

文章源網址:http://bbs.23dopod.com/viewthread.php?tid=17887

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.