RK3588 提高应用内存上限

android 12

Posted by LXG on November 24, 2025

应用内存过大导致OOM

rk3588_app_memory

private_other 内存过大导致OOM

App 主要跑人工智能模型(大模型权重 / 大量 mmap / GPU/NPU buffer / native heap)

目标是 降低 private_other(mmap/anon/ion)占用、避免 OOM、并提升模型加载与推理稳定性

内存图像

cat proc/meminfo


MemTotal: 7848664 kB
MemFree: 4311224 kB
MemAvailable: 5675652 kB
Buffers: 3656 kB
Cached: 2121248 kB
SwapCached: 0 kB
Active: 301268 kB
Inactive: 1825472 kB
Active(anon): 3476 kB
Inactive(anon): 745896 kB
Active(file): 297792 kB
Inactive(file): 1079576 kB
Unevictable: 738256 kB
Mlocked: 116116 kB
SwapTotal: 3924328 kB
SwapFree: 3924328 kB
Dirty: 356 kB
Writeback: 0 kB
AnonPages: 740152 kB
Mapped: 1232804 kB    // 此项很大
Shmem: 632164 kB
KReclaimable: 95560 kB
Slab: 169460 kB
SReclaimable: 62016 kB
SUnreclaim: 107444 kB
KernelStack: 18992 kB
ShadowCallStack: 4780 kB
PageTables: 43052 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 7848660 kB
Committed_AS: 50405152 kB
VmallocTotal: 262930368 kB
VmallocUsed: 53384 kB
VmallocChunk: 0 kB
Percpu: 7648 kB
CmaTotal: 131072 kB
CmaAllocated: 4160 kB
CmaReleased: 126912 kB
CmaFree: 126912 kB

OOM 根本原因:

  • App private_other 占用很高 → 大量 mmap/anonymouse mapping
  • Mapped 1.18 GB + Shmem 617 MB → 总地址空间分布碎片化
  • Linux max_map_count=65530 限制 → mmap 太多会导致 ENOMEM

dumpsys meminfo


>dumpsys meminfo com.rockchip.gpadc.common
Applications Memory Usage (in Kilobytes):
Uptime: 90646583 Realtime: 90646583

** MEMINFO in pid 2612 [com.rockchip.gpadc.common] **
                   Pss  Private  Private     Swap      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap   139712   139260        0        0   141572   174164        0    18365
  Dalvik Heap    29830    28248        0        0    36212    22775    11388    11387
 Dalvik Other     4910     2216        0        0     8620                           
        Stack     4121     4120        0        0     4132                           
       Ashmem      145       80        0        0      848                           
    Other dev   622176   510908   111268        0   622460                           
     .so mmap    25405      252    11672        0    56288                           
    .jar mmap     1618        0        0        0    27000                           
    .apk mmap    28744     2488    25840        0    31100                           
    .ttf mmap      103        0        0        0      388                           
    .dex mmap    18772        4    18728        0    19188                           
    .oat mmap     3682        0      448        0    12432                           
    .art mmap     3648      852        0        0    14816                           
   Other mmap     1799        8      472        0     6128                           
      Unknown     2093     2004        0        0     2528                           
        TOTAL   886758   690440   168428        0   983712   196939    11388    29752
 
 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:    29100                          51028
         Native Heap:   139260                         141572
                Code:    59432                         151344
               Stack:     4120                           4132
            Graphics:        0                              0
       Private Other:   626956
              System:    27890
             Unknown:                                  635636
 
           TOTAL PSS:   886758            TOTAL RSS:   983712      TOTAL SWAP (KB):        0
 
 Objects
               Views:       30         ViewRootImpl:        2
         AppContexts:        8           Activities:        3
              Assets:        8        AssetManagers:        0
       Local Binders:       15        Proxy Binders:       39
       Parcel memory:        9         Parcel count:       38
    Death Recipients:        1      OpenSSL Sockets:        0
            WebViews:        0
 
 SQL
         MEMORY_USED:       68
  PAGECACHE_OVERFLOW:       12          MALLOC_SIZE:       46
 
 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       24             17         0/15/1  /storage/emulated/0/xintian-sort/db/sort.db

sys.lmk.minfree_levels

这个参数控制 lmkd 在不同内存压力下会杀死哪些优先级的进程


[sys.lmk.minfree_levels]: [18432:0,23040:100,27648:200,32256:250,55296:900,80640:950]

18432:0        → 可用 RAM < 72 MB   → 允许杀 adj ≥ 0(实际不会杀前台)
23040:100      → 可用 RAM < 90 MB   → 杀 adj ≥ 100 的进程
27648:200      → 可用 RAM < 108 MB  → 杀 adj ≥ 200
32256:250      → 可用 RAM < 126 MB  → 杀 adj ≥ 250
55296:900      → 可用 RAM < 216 MB  → 杀 adj ≥ 900
80640:950      → 可用 RAM < 315 MB  → 杀 adj ≥ 950(缓存最弱进程)

设备是RK3588 8G 内存, 可用内存还有很多,而且应用是前台应用,因此不太可能是sys.lmk.minfree_levels触发导致的OOM

可能原因

你的 AI 应用超过了 Android 对单进程的最大内存限制,而不是系统整体内存不足

单个应用最多只能用约 3GB 左右的虚拟地址空间(64-bit 条件下)

类型 默认值 (64-bit)
Java 堆 maxMemory() 约 512MB~1.5GB(取决于 dalvik props)
native heap (malloc) 可达 3GB,但受 ASLR & VMA 限制
private_other(mmap) 多时容易导致 address-space OOM

private_other 多通常说明你大量使用 mmap 加载模型。

为什么你 private_other 很高却 OOM?

因为 mmap 数量过多 → VMA 数过多 → 触发 OOM:

  • Android 和 Linux 默认 max_map_count = 65530
  • 大模型(如 500MB+),如果分成几百个文件页映射,会很容易接近极限

解决方案-永久扩大进程 mmap 限制

device/rockchip/common/init.rk3588.rc


write /proc/sys/vm/max_map_count 262144

  • write /proc/sys/vm/max_map_count 262144 → 可以暂时缓解 OOM
  • 但单独做这一步不能根治,真正可靠的方法是 合并 mmap + buffer pool

RK3568 单个应用启动速度优化

属性 触发时机 当前值 含义 / 作用 优点 缺点 / 注意事项
pm.dexopt.ab-ota A/B OTA 分区切换后优化 speed-profile 对 OTA 后的应用/系统库进行 profile-guided AOT 优化 安装后热点代码快速可用,平衡 OTA 时间与性能 如果想最快启动可改为 speed,会增加 OTA 优化时间
pm.dexopt.bg-dexopt 系统空闲时后台优化 speed-profile 后台 profile-guided dexopt,优先优化热点代码 逐步优化,降低首次启动延迟,CPU 占用温和 全量 speed 可更激进,但后台会占用更多资源
pm.dexopt.boot 系统每次启动 verify 引导阶段只做 dex 验证,不做完整 AOT 启动快,开机延迟低 运行时仍依赖 JIT,启动流畅度有限
pm.dexopt.first-boot 系统或应用首次引导 quicken 轻量 quickening 优化,提高首次运行性能 首次体验比 verify 流畅,安装延迟小 不如全 AOT 快,长期性能需后台补充
pm.dexopt.inactive 对长时间未使用的包 verify 对 inactive 包只做验证 节省存储和安装/优化时间 包再次使用时仍需 JIT 或后台优化
pm.dexopt.install APK 安装时 speed-profile 安装时对热点 dex 做 AOT,其他由 JIT 安装速度适中,常用代码优化好 全量 speed 可更快运行,但安装耗时和存储占用增加
pm.dexopt.shared 共享库 / 被多个用户或进程共享的 dex speed 对共享 dex 做完整 AOT 多进程启动快,系统级共享库性能高 占用更多存储和安装时间

最小影响的修改方式


diff --git a/build/make/target/product/runtime_libart.mk b/build/make/target/product/runtime_libart.mk
index 693b686fbb..ec90d9d59c 100644
--- a/build/make/target/product/runtime_libart.mk
+++ b/build/make/target/product/runtime_libart.mk
@@ -68,9 +68,10 @@ endif
 # The install filter is speed-profile in order to enable the use of
 # profiles from the dex metadata files. Note that if a profile is not provided
 # or if it is empty speed-profile is equivalent to (quicken + empty app image).
+# modify by lixiaogang for app start speed
 PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
-    pm.dexopt.install=speed-profile \
-    pm.dexopt.bg-dexopt=speed-profile \
+    pm.dexopt.install=speed \
+    pm.dexopt.bg-dexopt=speed \
     pm.dexopt.ab-ota=speed-profile \
     pm.dexopt.inactive=verify \
     pm.dexopt.shared=speed