今天遇到一个用户报障说应用被 OOM 杀掉而且机器还会卡死,然后发了一个 free -m 显示的截图非常诡异的显示 swap 可用的大小远远大于 swap 总大小。

从下面的报障截图可以看到,free 命令显示的 swap 分区大小确实不正常。

![free result]](/assets/images/misc/centos6.7-swap-bug.png)

从 dmesg 内核的日志里,可以看到有进程被 OOM 杀掉了(后来证实,确实是应用有严重的内存泄漏问题,所以这里不用理会)。

Feb 28 13:14:01 localhost kernel: Out of memory: Kill process 77694 (deadbeef) score 979 or sacrifice child
Feb 28 13:14:01 localhost kernel: Killed process 77694, UID 99, (deadbeef) total-vm:117746984kB, anon-rss:32145468kB, file-rss:108kB

这里还是回到 free 的诡异输出上,接着我尝试把 swap 关掉,看看是什么效果。

# swapoff -a
# free -g
total       used       free     shared    buffers     cached
Mem:            31          1         30          0          0          0
-/+ buffers/cache:          0         30
Swap:            0 1717986868        500

这个输出就更吓人了,Swap 的 total 为 0,但是 used 却是一个非常大的数字(注意:free 输出的单位为 GB)。

看到这里,显然就觉得系统有问题了,再看看 /proc/meminfo。

# cat /proc/meminfo

这里略去详细的输出,但是从输出中可以看到如下和 swap 相关的信息

SwapTotal:             0 kB
SwapFree:       524772512 kB

free -g 显示的结果里,Swap free 为 500GB,实际上刚好是这里的 SwapFree 换算成 GB 后的结果。 而 free -g 中显示的 Swap used 就是一个负数了,所以看起来非常大。

由于 /rpoc/meminfo 是一个 kernel 导出到 user space 的文件,所以可以确定这是一个 kernel 的 bug。 而实际上这确实是一个 kernel bug,参考 RedHat 官方 kernel 更新

所以,解决办法就是安装了 CentOS 6.7 之后,执行下 yum update 或者 yum update kernel 升级一下 kernel 然后重启即可。