问题

拉了个golang项目要部署在一台1core512m12g的扶贫主机上编译,go build的时候报:collect2: fatal error: ld terminated with signal 9 [Killed]正常是系统内存或Swap不足导致ld被系统强制终止。

思路

因为我们用的是扶贫主机,必然是这个问题无疑了,闪过几个方案:

  1. 设置GOMAXPROCS=1编译时只用1核(export GOMAXPROCS=2),如果是make就是make -j1,但是我本来就只有1core,无意义
  2. 清理缓存sync && echo 3 > /proc/sys/vm/drop_caches,其实无济于事,那点内存塞牙缝不够
  3. 动代码减少多余的依赖库或文件,减少代码体积。动代码是不可能动的了,还可以编译的时候禁用调试信息以减少内存占用go build -ldflags "-w -s",但是试了一下有优化效果但内存还是不够
  4. 用swap,swap终于有用武之地了

实操

使用swap: sudo dd if=/dev/zero of=/swapfile bs=1G count=2 报错 dd: memory exhausted by input buffer 由于块大小(bs=1G)过大,系统无法分配连续内存 搞错了,重来: dd if=/dev/zero of=/swapfile bs=1M count=2048 bs=1M 分 2048 次写入 1MB 的块(大小 2G),避免一次性申请大内存 这下可以了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mkswap /swapfile
swapon /swapfile
# 看到2G已经用了
df -h
# 2G大小
ls -lh /swapfile
# 只给root权限
chmod 600 /swapfile
# 看一眼激活没
sudo swapon --show
# 控制内核使用交换空间的频率,默认 60,建议设为 10~30,但是我们是一次性的,编译完就没啥用了所以不太有必要做
echo 'vm.swappiness=30' >> /etc/sysctl.conf

编译

CGO_ENABLED=1 go build -ldflags "-w -s"顺利通过。

清理

我们是一次性的,清理一下swap省点空间之后用不着,释放swap:

1
2
3
swapoff /swapfile
rm -fr /swapfile
df -h