Android 爛裝置想跑人臉辨識2 – 記憶體優化-無用系統服務out

高通 QM215 的原生 Android 10 BSP 剛編譯出來,開機什麼 App 都沒開就吃掉 1.3GB RAM。

在 2GB 的破板子上,剩下的 700MB 要塞 950MB 的雙鏡頭串流與 300MB 的 AI 模型,物理上直接爆炸。

我們做的是 7×24 小時掛在牆上的專用門禁機,不是手機。它不需要音樂、通話、輸入法,甚至連電池都沒有。

瘦身不能無腦拿鋸子亂改 Java 源碼。我們分兩階段動刀:先走 AOSP 原廠標準規範,再依門禁機物理特性極限抽脂。


第一階段:AOSP 工業界標準規範(零侵入瘦身)

Google 與晶片廠對低記憶體設備早有標準規範,一行 Java 代碼都不用改:

1. 繼承 Google go_defaults.mk(Android Go 模式)

在產品 device.mk 開頭引入:

# 引入 Android Go 輕量化配置
$(call inherit-product, build/make/target/product/go_defaults.mk)

底層自動生效 ro.config.low_ram=true,關閉多視窗、動態桌布與視窗陰影,並將背景快取進程上限從 32 壓到 3 個。

2. 在 BoardConfig.mk 宣告 TARGET_NO_TELEPHONY := true

門禁機沒有 SIM 卡與 4G 模組,直接由編譯系統剔除基頻:

TARGET_NO_TELEPHONY := true   # 拔除 RIL 與通話 Daemon
TARGET_NO_RADIO := true       # 關閉射頻通訊
BOARD_HAVE_BLUETOOTH := true  # 保留藍牙 (BLE)

3. 移除 permissions/*.xml(讓 SystemServer 自然跳過)

SystemServer 啟動服務前會檢查 pm.hasSystemFeature()。只要在 device.mk 中不把對應 XML 複製到 /system/etc/permissions/,服務就不會實體化:

  • 移除 android.hardware.nfc.xml:NfcService 不啟動。
  • 移除 android.software.print.xml:PrintManager 不啟動。
  • 移除 android.hardware.telephony.xml:TelephonyRegistry 不啟動。
  • 移除 android.hardware.location.gps.xml:LocationManager 忽略 GPS。

第二階段:門禁機專屬的極限 Kiosk 抽脂(再榨 220MB)

走完標準規範後系統降至 1.0GB。接著針對「固定在牆上、插電運作、單一全螢幕 App」的特性剔除剩餘贅肉:

1. 幹掉 SystemUI 與 Launcher3(省 80MB ~ 120MB)

  • 人臉辨識 App 的 AndroidManifest.xml 宣告為 HOME,開機直達全螢幕,省去 Launcher3(省 40MB): <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" />
  • config.xml 關閉 Keyguard 鎖屏(省 15MB): <bool name="config_enableLockScreen">false</bool>

2. 拔除 LatinIME 輸入法(省 25MB ~ 35MB)

門禁機不需要虛擬鍵盤,PIN 碼由 App 內自繪。從 PRODUCT_PACKAGES 剔除 LatinIME,並在 config.xml 關閉:

&lt;bool name="config_showDefaultIME">false&lt;/bool>

3. 拔除電池監控(省 15MB + 省 CPU 輪詢)

門禁機接 12V 變壓器或 PoE,沒有鋰電池。關閉 PowerUI 低電量警告,屬性寫死 ro.boot.charger=0,避免系統輪詢電量與維護電池日誌。

4. 禁用 Zygote 預載 WebView(省 30MB ~ 50MB)

人臉辨識為純 Native/OpenGL 渲染。修改 ZygoteInit.java 跳過 WebViewFactory.prepareWebViewInZygote(),不讓進程分裂時繼承 Chromium 內核。

5. 裁剪音訊特效與無用 Codec(省 20MB)

清空 /vendor/etc/media_codecs.xml 裡的 Dolby/DTS/4K 解碼外掛,停用 audioserver 音效處理器,只留 PCM 嗶聲與 TTS。

6. 鎖死螢幕旋轉與單用戶(省 15MB)

設備鎖死在牆上,build.prop 設定 fw.max_users=1,並鎖定方向 persist.sys.app.rotation=force_land(或 portrait),關閉陀螺儀輪詢。


理智的底線:必須誓死捍衛的命根子

  • BLE 藍牙協議棧(GATT Server):保留供工程師現場免插線配網與金鑰派發。
  • Wi-Fi 與 Ethernet(netmgrd):特徵庫離線同步與 WebSocket 推送必備。
  • thermal-engine:高通溫控守護,防止晶片在密閉機殼內過熱降頻或燒毀。
  • surfaceflinger / inputflinger:相機預覽與螢幕渲染核心。

戰果驗收:記憶體帳單

  • 原生高通 Android 10 BSP:開機常駐 1,300 MB
  • 第一階段(Go 模式 + 拔通話 + 特性裁減):降至 1,000 MB(省 300 MB)
  • 第二階段(Kiosk 極限裁減:Launcher/IME/電池/Webview):再降至 ~780 MB(省 220 MB)
  • 最終優化後系統常駐:780 MB(淨奪回 520MB 實體 RAM)

在 2GB RAM 的低配機上,我們為雙鏡頭串流(950MB)與 AI 模型(300MB)留出了超過 1.2GB 的純淨實體空間,徹底告別 OOM。


結語

  1. 先走標準規範:善用 go_defaults.mkTARGET_NO_TELEPHONY 與 Feature Flags 完成體制內瘦身。
  2. 再依場景裁減:針對門禁機「無桌面、無輸入法、無電池、純 Native」特性剔除剩餘贅肉。

這才是真正的系統級工程治理。


參考資料 (References)

  1. Android Go Edition Device Configuration: Google 官方 Android Go 低記憶體規範.
    https://source.android.com/docs/core/perf/low-ram
  2. AOSP System Features & Permissions: Managing system features via permission XMLs.
    https://source.android.com/docs/core/permissions/perms-features
  3. Android Enterprise Dedicated Device (Kiosk Mode): Single-app device deployment guidelines.
    https://developer.android.com/work/dpm/dedicated-devices

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *