Skip to content

当 Linux 系统内存使用非常紧张时,Linux 会自动杀死一些进程以释放内存。这些被杀死的进程被称为 OOM 进程(Out of Memory Process)。OOM Killer 是 Linux 内核的一部分,它会在系统内存不足时自动运行,以释放内存。

查看被killed的进程

那么如何查看被killed原因呢?

内存不够

方法1是查看linux 系统日志.

shell
vim /var/log/messages

如果出现 kernel: Out of memory: Killed process意味着整个系统的内存已经不足,如果不杀死进程的话,就会导致系统的崩溃.

linux-killed-message-filter

设定kill优先度

2.1 完全关掉oom

shell
sysctl vm.overcommit_memory=2
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf

2.2 出现 Out Of Memory 之后重启

shell
sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf

2.3 优先考虑kill这个进程

shell
echo 10 > /proc/[PID]/oom_adj

2.4 尽量不去kill这个进程

shell
echo -15 > /proc/[PID]/oom_adj

2.5 不会kill这个进程

shell
echo -15 > /proc/[PID]/oom_adj

备注:

  • oom_adj的值在-16 到 +15之间,值越高被kill的优先度越高。
  • 当该值为-17时,系统将不会杀死指定pid的进程,而-16~15则会使得进程的 /proc/[pid]/oom_adj 值呈指数形式递增,即它们被杀掉的可能性呈指数递增。
  • 针对init(进程号为1)这个进程,无论该值设为多少都不会被杀。
  • 如果不能用杀死进程释放内存,则系统会崩溃。

如何解决

根源是内存不够,可以考虑临时添加一个swap分区,这是临时的,想根本解决就得添加内存了。

检查是否已经使用 swap:

shell
swapon -s

如果没有使用 swap,则可以开启 swap。

shell
vim /etc/sysctl.conf 

# 添加
vm.swappiness = 15

# 激活设置
sudo sysctl vm.swappiness=15
sysctl -p

# 查看当前swappiness值
cat /proc/sys/vm/swappiness 

sysctl -q vm.swappiness

说明: Swappiness 是 Linux 内核的一个属性,用于定义 Linux 系统使用 SWAP 空间的频率。swappiness值的范围是0 到100,较低的值会尽量减少内核对 SWAP 空间的使用,而较高的值会使 Linux 内核更积极地使用 SWAP 空间。linux的swappiness参数的默认设置为60,内存在使用到100-60=40%的时候,就开始出现有交换分区的使用。内存的速度会比磁盘快很多,这样子会加大系统io,同时造的成大量页的换进换出,严重影响系统的性能,所以我们在操作系统层面,要尽可能使用内存,对该参数进行调整。

Swap分区使用

创建交换分区

新建一个分区,并格式化为swap格式。

shell
#将分区格式化成swap格式
mkswap /dev/sdb6
Setting up swapspace version 1, size = 2104476 KiB
no label, UUID=41687bb2-c775-489c-9b32-1e4be73c233b   #看见没有,这里是“no label”,是因为我没有定义卷标名。

mkswap -L myswap /dev/sdb6   #用-L参数定义一个卷标名。
Setting up swapspace version 1, size = 2104476 KiB
LABEL=myswap, UUID=0553b99a-ee75-4476-8eda-70c591206467  #看见没,“LABEL=myswap”这就是我定义的卷标名称。
  1. 创建一个新的分区 首先,使用 fdisk 或 parted 工具对磁盘进行分区。假设我们使用的是 /dev/sdb 作为目标磁盘。
shell
sudo fdisk /dev/sdb

在 fdisk 工具中执行以下操作:

输入 n 创建一个新分区。 输入 p 选择主分区。 输入分区号(例如 1)。 设置分区的大小(例如 +2G 表示分区大小为 2GB)。 输入 t 修改分区类型。 输入 82 设置交换分区类型。 输入 w 保存并退出。

  1. 格式化分区为交换类型

创建好交换分区后,需要使用 mkswap 命令将其格式化为交换空间:

shell
sudo mkswap /dev/sdb1

/dev/sdb1 是你新创建的交换分区。

  1. 启用交换分区

使用 swapon 命令启用交换分区:

shell
sudo swapon /dev/sdb1
  1. 检查交换分区是否启用

再次使用 swapon --show 或 free -h 查看交换分区是否已经成功启用。

shell
swapon --show

创建交换文件

如果你不想创建额外的交换分区,另一种方法是创建一个交换文件来作为交换空间。

  1. 创建交换文件
shell
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048

这里创建了一个 2GB 的交换文件(count=2048 代表 2048 MB)。

  1. 设置交换文件权限

确保交换文件的权限正确,只有 root 用户能读取和写入:

shell
sudo chmod 600 /swapfile
  1. 格式化交换文件

使用 mkswap 格式化交换文件:

shell
sudo mkswap /swapfile
  1. 启用交换文件

启用交换文件:

sell
sudo swapon /swapfile
  1. 设置开机自动启用交换文件

编辑 /etc/fstab 文件,添加如下行:

shell
/swapfile none swap sw 0 0

保存并退出。

查看交换空间:使用 free -h、swapon --show、lsblk 等命令查看当前交换空间。

操作案例

shell
dd if=/dev/zero of=/data/swapfile bs=1M count=8192
chmod 600 /data/swapfile
sudo mkswap /data/swapfile
swapon /data/swapfile

# 加入开机启动挂载 swapfile
vim /etc/fstab
/data/swapfile                               none            swap    sw              0       0

查看交换空间:使用 free -h、swapon --show、lsblk 等命令查看当前交换空间。