Ubuntu系统编译Android SDK 由于系统内存不足导致编译失败问题解决

1 环境背景

1.1 基础信息

Ubuntu系统版本:ubuntu 16.04 LTS

电脑主板CPU信息:Intel® Core™ i5-3470 CPU @ 3.20GHz × 4

电脑主板内存:15.6 GiB

需要编译的Android SDK版本:Android13

1.2 编译报错信息

1.2.1 make -j4 报错 log

============================================
[100% 1/1] analyzing Android.bp files and generating ninja file at out/soong/build.ninja
FAILED: out/soong/build.ninja
cd "$(dirname "out/host/linux-x86/bin/soong_build")" && BUILDER="$PWD/$(basename "out/host/linux-x86/bin/soong_build")" && cd / && env -i  "$BUILDER"     --top "$TOP"     --soong_out "out/soong"     --out "out"     -o out/soong/build.ninja --globListDir build --globFile out/soong/globs-build.ninja -t -l out/.module_paths/Android.bp.list --available_env out/soong/soong.environment.available --used_env out/soong/soong.environment.used.build Android.bp
codec2-config: sdkVersion[33]
use aw hw vp9!
codec2-ic type : [a523]
registry_table has NOT been set. Please check it.
cedarx-config: sdkVersion[33], board[saturn], platformconfig[YES]
cedarx-ic type : [a523]
cedarc-config: sdkVersion[33], board[saturn], platformconfig[YES], cryptolevel[1], playreadytype[]
registry_table has NOT been set. Please check it.
/bin/sh: line 1:    23 Killed                  env -i "$BUILDER" --top "$TOP" --soong_out "out/soong" --out "out" -o out/soong/build.ninja --globListDir build --globFile out/soong/globs-build.ninja -t -l out/.module_paths/Android.bp.list --available_env out/soong/soong.environment.available --used_env out/soong/soong.environment.used.build Android.bp
19:14:04 soong bootstrap failed with: exit status 1
ninja: build stopped: subcommand failed.

#### failed to build some targets (09:26 (mm:ss)) ####
#### failed to build some targets (09:26 (mm:ss)) ####

1.2.2 Ubuntu系统dmesg报错 log

[  974.660801] Out of memory: Kill process 8160 (soong_build) score 880 or sacrifice child
[  974.661346] Killed process 8160 (soong_build) total-vm:16902592kB, anon-rss:15508200kB, file-rss:0kB, shmem-rss:0kB
[  975.184685] oom_reaper: reaped process 8160 (soong_build), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

由以上log信息得知,SDK编译失败是由于系统内存不足,编译进程被系统kill掉导致编译中断。在Android高版本编译时经常会遇到framework一些相关任务编译时经常把内存吃满导致内存不足这种现象。

2 解决方法

2.1 增加主板物理内存

如果主机主板可以支持更大的内存,建议购买内存条来加大系统内存,提升主板性能。注意增加的内存条最好要跟之前主板所使用的内存条的型号跟频率要一致,以减少不必要的麻烦。由于我所使用的电脑主板最大内存容量只支持到16GB,所以此路不通,除非直接更换电脑主板。

2.2 减少编译线程

当你输入编译命令make -j4 的时候,会有以下提示,这是官方所建议的减少编译线程来解决编译时消耗内存过大的情况。

15:17:31 ************************************************************
15:17:31 You are building on a machine with 15.6GB of RAM
15:17:31
15:17:31 The minimum required amount of free memory is around 16GB,
15:17:31 and even with that, some configurations may not work.
15:17:31
15:17:31 If you run into segfaults or other errors, try reducing your
15:17:31 -j value.
15:17:31 ************************************************************

所以这个时候你就把:make -j4变成 make -j2或make -j1 (-j 1代表只用一个线程编译,会导致编译非常缓慢)

2.3 增加swap内存

        Linux中Swap(即:交换分区),类似于Windows的虚拟内存,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。Android是基于Linux的操作系统,所以也可以使用Swap分区来提升系统运行效率。
        交换分区,英文的说法是swap,意思是“交换”、“实物交易”。它的功能就是在内存不够的情况下,操作系统先把内存中暂时不用的数据,存到硬盘的交换空间,腾出内存来让别的程序运行,和Windows的虚拟内存(pagefile.sys)的作用是一样的。

2.3.1 查看swap分区大小

chris@lc:/work2/SDK/A527/A527_Android13TableV1.2/android$ sudo fdisk -l
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x00016001

Device     Boot     Start        End    Sectors   Size Id Type
/dev/sda1  *         2048  299999231  299997184 143.1G 83 Linux
/dev/sda2       300001278 1953523711 1653522434 788.5G  5 Extended
/dev/sda5       300001280  340000766   39999487  19.1G 83 Linux
/dev/sda6       340000768  343998463    3997696   1.9G 82 Linux swap / Solaris
/dev/sda7       344000512  345999359    1998848   976M 83 Linux
/dev/sda8       346001408 1953523711 1607522304 766.5G 83 Linux

chris@lc:/work2/SDK/A527/A527_Android13TableV1.2/android$ free -m
                    total           used          free      shared     buff/cache   available
Mem:           15936        4655         149        2117       11131          8767
Swap:          1951          0               1951

2.3.2 创建文件

sudo dd if=/dev/zero of=/swapfile bs=1M count=20480
of:文件的保存路径
bs=1M count=20480:文件的大小为1MB*20480 = 20GB

在linux中,“/dev/zero”是一个特殊的设备文件,它会不断地产生二进制零值。在使用“dd”命令创建文件时,如果将输入文件(if)指定为“/dev/zero”,则会从该设备文件读取无限数量的二进制零值,以填充目标文件。

在创建Swap文件时,我们通常使用“/dev/zero”来填充文件中的内容,因为Swap文件中的内容在使用过程中并不重要,只需要占用一定的磁盘空间即可。而使用“/dev/zero”填充Swap文件可以确保文件中的所有位都被设置为零,从而避免在使用Swap文件时发生数据泄漏或错误。

因此,“sudo dd if=/dev/zero of=/swapfile bs=1M count=20480”命令中的“if=/dev/zero”参数的作用是从“if=/dev/zero”参数的作用是从“/dev/zero”设备文件中读取数据,并将其写入名为“/swapfile”的文件中,已创建一个大小为20GB的Swap文件。

2.3.3 将文件格式化为swap文件

sudo mkswap /swapfile

2.3.4 挂载swap文件

sudo swapon /swapfile

这样,虚拟内存就扩充好了,可以通过命令free -m查看内存情况:

chris@lc:/work2/SDK/A527/A527_Android13TableV1.2/android$ free -m
                   total           used        free        shared    buff/cache   available
Mem:          15936        4675        168        2394       11092          8471
Swap:          22431        0             22431

Swap已经由之前的1951M(1.9GB)增加到现在的22431M(21.9GB)了,Swap虚拟内存增加成功。

2.3.4 设置剩余最小内存触发swap

sudo vi /etc/sysctl.conf

在末尾加入:
vm.min_free_kbytes=2048000

在空闲内存只剩2GB时触发使用虚拟内存。

2.3.5 开机自动挂载swap文件

系统重启的话,需要重新挂载swap文件,可以像挂载硬盘一样开机自动挂载:

sudo vim /etc/fstab

在末尾加入:

/swapfile none swap sw 0 0

猜你喜欢

转载自blog.csdn.net/Chris_1994/article/details/135017508