MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

Firefox OS 會運行在一些記憶體容量不大的裝置上,當程序用盡了記憶體,系統核心就必須關閉其他程序好釋放出記憶體使用。本文旨在描述記憶體關閉和記憶體不足通知如何運作、如何控制關閉那些程序,以確保當記憶體不夠時,主系統還是可以運作。

記憶體不足時會有兩個系統介入管理: Low memory killer (LMK) Low memory notifications.

Low memory killer

LMK 是 Android 核心的次系統,這個次系統負責關閉程序好騰出記憶體使用。為了決定程序關閉優先順序,每一個程序都會透過 /proc/<pid>/oom_adj or /proc/<pid>/oom_score_adj files 被賦予一個優先值,這個優先值為調整分數(adjustment score 或 oom_adj)。

一般來說 oom_adj 值越大,程序越容易被刪除,LMK 提供多個層級,每個層級對應到一定容量的可用記憶體以及最小 oom_adj 值。當可用記憶體掉到某一個層級,所有 oom_adj 值大於該層級 oom_adj 值的程序都有可能被關閉,LMK 會從占用最多記憶體的程序開始一個一個關閉,直到可用記憶體回復到安全層級為止。

Note: 被 LMK 關閉的背景 app 仍然以 "殭屍 app" 的形式存在在程序管理員 (task manager),下次再回到該 app,app 會被重新喚醒。目前最大殭屍 app 的數量是 10。

Note: 為了記憶體不足被關閉的 app 不一定就是造成記憶體不足的原因。

程序關閉優先順序

Firefox OS 關閉 app 的優先順序是由每個 app 給定的優先層級和相關聯的 OOM 調整分數所決定 (現有值都存在 pref):

  1. 最先關閉的 app 是背景 app,最近最少使用的。
  2. 第二是 homescreen app。
  3. 接下來是使用者可察覺的背景 app (例如,在背景撥放音樂的程式,或高優先 (high-priority)、或持有 cpu wakelock 並且註冊有系統訊息處理器(system messages handler) 的 app)。
  4. 第四是鍵盤程式。
  5. 前景 (Foreground) app 則是第五順位被關閉的 app。
  6. 最後則是前景高優先 (high-priority)、或持有 cpu wakelock 的前景 app。

Note: 大部分在前景的子程序持有為 2 的oom_adj,背景子程序則持有 3 ~ 6 的 oom_adj,背景子程序到底會持有多大 oom_adj 值取決於許多因素,比如說是否撥放音月或是否屬於 homescreen app。

下面是例外:

  • 主程序永遠不會被關閉,因為一旦主程序被關閉,所有子程序也會被關閉,系統會重新啟動;主程序的 oom_adj 為 0。
  • 為了加速新程序啟動,會有一個 preallocated process 被一直保留著,這個程序耗費的記憶體相當少,但卻可以顯著加速程式啟動。除非所有能關閉的程序都關閉了,但主程序需要的記憶體依然不足,這時 preallocated process 才會被關閉。

記憶體過低通知

第二個釋放記憶體的機制是記憶體過低通知。當可用記憶體量低過一定的門檻值,LMK 便會向使用者空間 (userspace) 發出記憶體過低通知,系統 app 和一般使用者 app 都會等待這個通知,然後透過觀察器服務 (observer service) 發出 memory-pressure 事件回應之;這個事件 app 不會直接看見,只有 C++ 和 Chrome JS 程式碼會看到,在 Gecko 裡我們從這個事件中會盡一切可能釋放記憶體 — 通常是刪除內部快取 (images, DNS, sqlite, 等等),拋棄可以回復的物件 (比如 WebGL contexts) 還有執行垃圾回收機制。

當碰到記憶體過低狀況時,第一個發出的 memory-pressure 事件會有 low-memory 負載,倘若經過預定的5秒後我們依然處於記憶體過低狀態,另一個 memory-pressure 事件會發出,不過這一次是帶著 low-memory-ongoing 負載,這個時候我們持續處於記憶體過低狀態,很明顯地像一些垃圾回收機制等大動作的作法也不夠了,所以其他一些更低階的記憶體釋放作法會被採行。

LMK 和記憶體過低通知如何協同運作

目前記憶體過低門檻介於 LMK 的背景 app 層級(大於)和 homescreen 層級(小於)之間,所以整體記憶體不足的反應機制如下:

  1. 關閉最近最不常用的背景 app。
  2. 當記憶體依然不足,發出 memory-pressure 事件通知給所有的 app。
  3. 當記憶體依然不足,每5秒發出 memory-pressure 事件,但標記為 ongoing 讓垃圾回收機制不要回應。
  4. 關閉 homescreen.
  5. 關閉使用者可察覺或高優先值的背景 app。
  6. 關閉運作中的鍵盤 app。
  7. 關閉前景 app。
  8. 關閉高優先值的前景 app。
  9. 關閉 preallocated 程序。

文件標籤與貢獻者

 此頁面的貢獻者: chrisdavidmills, foxbrush
 最近更新: chrisdavidmills,