記憶體是 Android 裝置上重要且有限的資源。身為 Android 平台開發人員或原始設備製造商 (OEM),您必須瞭解記憶體在各個層級 (從 Java 執行階段到 Linux 核心) 的運作方式,才能建構高效能且穩定的系統。
本指南將全面介紹 Android 記憶體架構、可用的分析工具,以及實用練習,協助您找出並解決記憶體相關問題。
目標
完成本指南後,您將能夠:
- 說明 Android 記憶體的基本概念,包括 Zygote 程序模型和記憶體對應檔案。
- 區分常設集大小 (RSS)、比例集大小 (PSS) 和不重複集大小 (USS)。
- 使用
dumpsys meminfo和showmap等標準指令列工具,快速評估記憶體用量。 - 使用 AHAT 擷取及分析 Java 記憶體快照資料,找出流失和過度分配問題。
- 使用 Perfetto 和
heapprofd,剖析整個系統的 Java 和原生記憶體。 - 瞭解系統層級的記憶體壓力指標,例如壓力停滯資訊 (PSI),並監控記憶體不足終止工具 (LMK) 活動。
- 觀察核心層級的回收活動,包括 ZRAM 交換和頁面快取清除。
指南結構
本指南分為以下幾個部分,建議依序閱讀:
- 基本概念:Android 記憶體的核心技術原則。
- 快速評估工具:使用
meminfo、showmap和procstats快速分類。 - 分析 Java 記憶體:使用 AHAT 深入分析 Java 堆積。
- 點陣圖和記憶體:瞭解圖片對 RAM 的影響,並使用工具進行分析。
- 分析原生記憶體:使用 Perfetto 和
heapprofd分析 C/C++ 記憶體。 - WebView 和記憶體:瞭解 WebView 的多程序架構和記憶體用量。
- 應用程式程式碼是記憶體:瞭解類別載入和 dex 膨脹對 RAM 的影響。
- 執行緒和記憶體:分析原生執行緒堆疊的成本。
- 記憶體位置和效能:瞭解資料存取模式如何影響 CPU 效能。
- 服務繫結和程序狀態:瞭解跨程序依附元件如何影響 OOM 分數。
- 系統層級疑難排解:監控 PSI、LMK、ZRAM 交換和頁面快取清除。
- 記憶體回收:剔除和交換:瞭解 memcg、計費和主動回收,以及
memory.reclaim。 - kswapd 和 lmkd 互動:瞭解 kswapd 和 lmkd 在壓力下如何協同運作。
- 將記憶體頁面傳回 OS:使用
madvise和posix_fadvise將未使用的堆積頁面和檔案快取頁面傳回核心。 - 使用精簡程序維持背景工作:將背景服務和工作站移至專屬程序,避免 UI 和圖形記憶體維持較高優先順序。
事前準備和環境
本指南提供參考工作流程、基準資料和個案研究,說明如何診斷及解決 Android 記憶體問題。
- 分析工具:本指南中的技術主要使用標準 Android 效能工具,包括 Perfetto、
dumpsys meminfo、showmap和 AHAT。 - Root 權限:部分系統層級診斷工作流程 (例如檢查核心記憶體壓力或硬體 PMU 計數器),需要使用者偵錯裝置或模擬器建構作業的提升 Root 權限 (
adb root)。
從這裡開始:基本概念