增加交换分区 swap 解决编译时内存不足问题

背景

在 Linux 系统上编译大型程序时,可能遇到如下编译错误:

1
2
c++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report

经过查资料,大概率是编译时内存不够导致的,除了增加物理内存外 (花银子),短期可以通过增加交换分区 swap 来解决 (时间换空间)。

什么是交换分区 swap

Linux 中的交换分区 (swap),类似于 Windows 的虚拟内存,就是当内存不足 (RAM) 的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。

功能:在内存不够的情况下,操作系统先把内存中暂时不用的数据,存到硬盘的交换空间,腾出内存来让别的程序运行,和 Windows 的虚拟内存(pagefile.sys)的作用是相似的。

副作用:虽然这个 swap 分区能够作为 "虚拟" 的内存,但它的速度比物理内存可是慢多了

如果需要更快的速度的话,并不能寄厚望于 swap,最好的办法仍然是加大物理内存,swap 分区只是临时的解决办法。

作用原理

计算机对内存分为物理内存虚拟内存(注意虚拟内存和虚拟地址空间的区别)。

  • 物理内存就是计算机的实际内存大小,由 RAM 芯片组成的。
  • 虚拟内存则是虚拟出来的,使用磁盘代替内存。虚拟内存的出现,让机器内存不够的情况得到部分解决。这里的虚拟内存,即所谓的 swap。

当程序运行起来后,由操作系统做具体虚拟内存到物理内存的替换和加载 (相应的页与段的虚拟内存管理)。

  • 当用户提交程序,然后产生进程,在机器上运行。机器会判断当前物理内存是否还有空闲允许进程调入内存运行,如果有那么则直接调入内存进行运行;如果没有,那么会根据优先级选择一个进程挂起,把该进程交换到 swap 中等待,然后把新的进程调入到内存中运行。
  • 根据这种换入和换出,实现了内存的循环利用,让用户感觉不到内存的限制。其中,swap 扮演了一个非常重要的角色,就是暂存被换出的进程。

如何增加交换分区

因为之前可能进行过 swap 扩容,所以第一步是把之前的交换分区关闭。

  1. 查看是否已经有 swap 分区

1
free -m
  1. 如果有,先把原来的 swap 关闭
1
2
3
su
swapoff -a
# 详细的用法可以:swapoff --help
  1. 扩展分区

交换分区的合理值,可以根据你系统内存的大小,以及所使用的程序,自行决定交换分区的大小。

1
2
3
4
5
6
7
8
9
# count 的大小就是增加的 swap 空间的大小,64M 是块大小,所以空间大小是 bs*count=1024MB
sudo dd if=/dev/zero of=/swapfile bs=64M count=16
# 把刚才空间格式化成 swap 格式
sudo mkswap /swapfile
# 该目录权限,不改的话,在下一步启动时会报 “swapon: /swapfile: ”
# “insecure permissions 0644, 0600 suggested.” 错误
chmod 0600 /swapfile
# 使用刚才创建的 swap 空间
sudo swapon /swapfile
  1. 关闭临时空间
1
swapoff -a
  1. 查看当前内存使用情况,确认交换分区设置成功。
1
free -m
  1. 其他命令
1
swapon -s # 可以查看当期swap的使用情况

References