首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 記憶體管理:LowMemory 與 OOM 機制深度解析

     編輯:程式設計綜合問答

核心機制對比

機制觸發條件執行主體行為開發者可控
Low Memory (onTrimMemory / onLowMemory)系統記憶體壓力大,App 進程優先級較低時Android Framework → App 進程回調 onTrimMemory(level) / onLowMemory(),App 主動釋放快取、圖片等非關鍵資源是(覆寫回調釋放資源)
OOM Killer (Out Of Memory)系統可用記憶體極低,需強制殺死進程釋放記憶體Linux Kernel (lowmemorykiller)根據 oom_score_adj 評分,從高分進程開始殺死(空進程 → 後台服務 → 前台 App)否(只能優化記憶體降低評分)

Low Memory 詳細機制

  • 回調層級:TRIM_MEMORY_UI_HIDDEN (UI 隱藏)、TRIM_MEMORY_RUNNING_LOW (記憶體較低)、TRIM_MEMORY_BACKGROUND (進入後台) 等。
  • 最佳回應:釋放圖片快取、清理記憶體敏感物件、調用 Glide.get(context).clearMemory() 等。
  • 不保證執行:系統可能直接 OOM Kill 而不回調。

OOM Killer 詳細機制

  • 評分計算:oom_score_adj 基礎分 + 記憶體佔用比例。可查 /proc//oom_score_adj 及 oom_score。
  • 進程分類(由低分到高分,越後越易被殺):
    1. 原生系統進程 (system_server, -1000)
    2. 持久進程 (Persistent, -800)
    3. 前台進程 (Foreground, 0)
    4. 可見進程 (Visible, 100)
    5. 服務進程 (Service, 200)
    6. 後台進程 (Cached/Empty, 900+)
  • 閾值配置:/sys/module/lowmemorykiller/parameters/minfree (頁數),對應不同 adj 等級的剩餘記憶體閾值。

開發者優化策略

1. 降低 OOM 評分(減少被殺機率)

  • 控制記憶體佔用:圖片壓縮、複用、弱參考、避免記憶體洩漏 (LeakCanary)。
  • 避免大型物件長駐:Bitmap、Cursor、大集合釋放及時。
  • 使用 android:isolatedProcess 隔離高記憶體組件(如圖片處理)。

2. 正確響應 Low Memory 回調


@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (level >= TRIM_MEMORY_RUNNING_LOW) {
        imageCache.evictAll();  // 釋放圖片快取
        gsonCache.clear();
    }
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    // 最後機會釋放非關鍵資源
}

3. 現代架構:ViewModel + SavedStateHandle

  • 資料存活於配置變更,不佔用 Activity 記憶體。
  • 進程被殺後自動恢復 UI 狀態。

常見誤區

  • 以為 Low Memory 和 OOM 是同一機制:前者是框架層回調(可控),後者是核心層強制殺進程(不可控)。
  • 註冊大量 BroadcastReceiver 監聽記憶體:無效,只有系統主動回調 App 進程。
  • 忽略記憶體洩漏:洩漏累積是 OOM 的主因,定期用 Profiler/LeakCanary 掃描。

總結

Low Memory = 禮貌通知請釋放資源;OOM = 強制執行死刑。開發者只能透過「平時節儉(優化記憶體)」+「收到通知快釋放(onTrimMemory)」來降低被 OOM Kill 風險,無法直接控制 OOM Killer。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved