Android 源码编译错误ninja failed with: signal: killed摘要在编译 Android 源码时出现ninja failed with: signal: killed通常是构建过程中内存不足被系统 OOM Killer 终止所致。本文通过创建并启用 4G swap 交换文件来扩充可用虚拟内存缓解编译期内存压力并给出开机自动挂载 swap 的配置方法帮助构建顺利通过。Android 源码编译错误ninja failed with: signal: killed#!/bin/bash # 建立swap文件 # 查看目前swap free -m # 建立 swap 文件大小 4G dd if/dev/zero of/var/swapfile bs1024 count4000000 # 启用虚拟内存将 swap 文件设置为 swap 分区文件 mkswap /var/swapfile # 注意insecure permissions 0644, 0600 suggested. chmod 600 /var/swapfile # 激活 swap启用分区交换文件 swapon /var/swapfile # 停用虚拟内存 #swapoff /var/swapfile # 查看内存和虚拟内存 free -m # 开机启用swap echo /var/swapfile swap swap defaults 0 0 /etc/fstab # 查看目前swap free -m问题成因分析ninja failed with: signal: killed并非编译语法错误而是构建进程被系统强制终止。Android 源码编译尤其是soong/ninja并行任务会同时拉起大量clang、javac进程瞬时内存占用极高当物理内存耗尽时Linux 的 OOM Killer 会挑选占用内存最多的进程发送SIGKILL于是 ninja 报告signal: killed。否是执行 Android 源码编译ninja 并行调度大量编译任务clang / javac 进程内存占用飙升物理内存是否耗尽编译正常继续触发 Linux OOM Killer向高内存进程发送 SIGKILLninja 报错 signal: killed创建并启用 swap 文件重新编译构建通过如何确认是否真的被 OOM Killer 终止在动手加 swap 之前建议先确认「signal: killed确实来自 OOM Killer」避免把其他原因如磁盘写满、进程被手动 kill误判为内存问题。下面三条命令可以互相印证。1. 查看内核日志中的 OOM 记录# 实时内核环形缓冲区中查找被杀的进程dmesg|grep-ikilled process# 若 dmesg 已被清空或权限受限可查看持久化的内核日志grep-ikilled process/var/log/kern.log# Debian/Ubuntu 之外的系统可尝试# grep -i killed process /var/log/messages典型输出如下[12345.678901] Out of memory: Killed process 24680 (clang) total-vm:8456320kB, anon-rss:6123456kB, file-rss:0kB, shmem-rss:0kB [12345.679012] oom_reaper: reaped process 24680 (clang), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB输出解读Out of memory: Killed process是 OOM Killer 出手的明确标志出现这一行基本可以判定为内存不足括号中的clang、javac、ninja等即被终止的进程名与编译报错时间点吻合即可确认total-vm是进程申请的虚拟内存总量anon-rss是实际驻留的物理内存数值越大说明该进程是当时的「内存大户」若日志里只有signal: killed而没有任何Out of memory记录则要转而排查磁盘空间、ulimit限制或人为 kill。2. 观察内存峰值判断是否逼近上限# 编译前先记录基线free-m# 另开一个终端每 2 秒采样一次内存观察编译期间的变化watch-n2free-m# 或者用 top 按内存排序盯住峰值top-o%MEMfree -m输出解读单位 MBtotal used free shared buff/cache available Mem: 15884 15230 120 356 534 210 Swap: 0 0 0available已降到接近 0而used几乎等于total说明物理内存已被吃满Swap一行为全 0意味着没有任何兜底空间一旦物理内存耗尽就只能触发 OOM编译过程中若free持续下降并在报错瞬间触底与dmesg中的 OOM 记录时间对应即可形成完整证据链。top -o %MEM中重点关注RES列若某个clang进程的RES达到数 GB 并持续增长同时系统free迅速减少就是典型的编译期内存峰值场景。3. 结论当dmesg/kern.log中出现Out of memory: Killed process且free -m显示available触底、Swap为 0 时即可确认本次ninja failed with: signal: killed由 OOM Killer 导致此时按上文创建并启用 swap 文件是有效的缓解手段。Swap 扩容处理流程下面的流程图对应文中脚本的执行顺序从检查内存到开机自动挂载形成完整的处理闭环。free -m 查看当前内存dd 创建 4G swapfilemkswap 格式化为 swapchmod 600 修正权限swapon 激活 swapfree -m 确认生效写入 /etc/fstab 开机自动挂载关键步骤说明步骤命令作用查看内存free -m确认物理内存与 swap 现状创建文件dd if/dev/zero of/var/swapfile bs1024 count4000000生成约 4G 的 swap 文件格式化mkswap /var/swapfile将文件标记为 swap 分区修正权限chmod 600 /var/swapfile避免 insecure permissions 警告激活swapon /var/swapfile立即启用虚拟内存持久化echo /var/swapfile swap swap defaults 0 0 /etc/fstab开机自动挂载提示若编译仍被 kill可进一步降低并行度如make -j4或调整soong的NINJA_ARGS并优先保证物理内存充足swap 仅作为兜底手段。