如何限制AOSP构建过程中ninja的内存与CPU资源占用?
AOSP 12编译时Ninja占满资源的解决方法
首先明确核心原因:AOSP 12中make仅作为编译入口,实际构建调度由Soong调用Ninja完成,直接给make传-j参数不会传递到Ninja进程,这是之前调整-j参数无效的根本原因。ZRam、增大Swap无法解决问题的原因是:并行编译任务瞬时占满物理内存时,系统会因大量Swap IO进入不可中断睡眠状态直接卡死,和Swap总容量无关。
以下是可落地的限制方案:
方案1:通过环境变量直接控制Ninja并行度(优先使用,无侵入)
Soong启动Ninja时会读取专用环境变量,不会继承make的-j参数,编译前在终端执行以下配置即可:
# 限制Ninja并行任务数为4,适配16G内存配置(单编译任务约占2-3G内存,留4G给系统进程) export NINJA_ARGS="-j4" # 额外限制Soong阶段调用Ninja的并行度,优先级高于NINJA_ARGS,避免被Soong默认值覆盖 export SOONG_NINJA_PARALLELISM=4 # 限制编译过程中Java进程的最大堆内存,避免Soong/Java编译任务无限制吃内存 export JAVA_TOOL_OPTIONS="-Xmx4g"
配置完成后正常执行编译命令(m/make均可),Ninja会严格遵守设定的并行数。等soong_build阶段跑完、进入后续模块编译阶段(单任务内存占用更低),可以把并行数调到6-7加快编译速度。
方案2:通过Cgroup做系统级硬限制(彻底避免卡死,最稳妥)
如果担心环境变量不生效,可以用Linux Cgroup给整个编译进程组设硬配额,不管Ninja怎么调度都不会突破限制:
- 切换到root权限创建编译专用Cgroup:
sudo su mkdir -p /sys/fs/cgroup/aosp-build # 限制CPU最大使用率为4个核心(对应8线程CPU的50%算力,留足够资源给系统交互) echo "400000 1000000" > /sys/fs/cgroup/aosp-build/cpu.max # 限制内存最大使用12G,超出后系统会优先杀编译进程,不会拖死整个系统 echo 12G > /sys/fs/cgroup/aosp-build/memory.max # 把当前终端的PID加入Cgroup,后续该终端启动的所有编译进程都受规则限制 echo $$ > /sys/fs/cgroup/aosp-build/cgroup.procs exit - 直接在该终端执行编译命令即可,不需要额外调整其他参数,资源使用率会被严格限制在设定的阈值内,不会出现系统完全卡死的情况。
避坑说明
- 不要在soong_build阶段开高于4的并行数:该阶段涉及framework层大量AIDL、资源、Java代码编译,单任务内存峰值可达3G,16G物理内存开超过4个并行任务必然触发内存耗尽。
- 不建议用
cpulimit/nice类工具限制:这类工具只能调整CPU调度优先级,无法限制内存使用,还是会出现内存占满卡死的问题。
内容的提问来源于stack exchange,提问作者turbos
相关产品推荐
相关产品推荐

