Linux 不使用交换,但触发了 OOM killer

Linux 不使用交换,但触发了 OOM killer

这个问题我已经困扰我很久了,我似乎无法解决它,基本上,我的 linux(32 位 3.2.6-3.fc16.i686.PAE)系统拒绝使用交换。当我运行

$ tail /dev/zero
tail: memory exhausted

它根本不使用交换区。它在用完物理 RAM 后就死机了。以下是相关详细信息。

$ free -m
             total       used       free     shared    buffers     cached
Mem:          8076       4652       3423          0        123        543
-/+ buffers/cache:       3985       4090
Swap:         8192        116       8076


$ cat /proc/sys/vm/swappiness 
60

$ ulimit -m
unlimited

$ cat /proc/sys/vm/overcommit_ratio
50

$ cat /proc/sys/vm/overcommit_memory 
0

我尝试将其设置为 1:

# sysctl vm.overcommit_memory=1
vm.overcommit_memory = 1


$ cat /proc/sys/vm/overcommit_memory 
1

再次尝试,结果相同。有什么想法吗?

答案1

它是 32 位 Linux,因此无法为应用程序分配超过 4GiB 的内存,因为它会耗尽其地址空间。您有 8GiB RAM,而且大部分是空闲的,因此无需使用交换空间即可分配 4096 MiB。

答案2

这个问题有点老了,但答案很简单:

tailing from/dev/zero没有任何用处。如果您只想要一个空字节流,请使用cat

tail(使用默认参数)将返回参数中的最后 10 行。由于/dev/zero是字符设备,它将开始从中读取数据块,直到最后(常规文件是向后扫描的)。读取的数据将保留,直到找到 10 行,然后将前几行从缓冲区中逐出。

行将由换行符分隔 - \n。由于/dev/zero不返回任何换行符,所有数据(迄今为止读取的所有空字节)仍被视为第一行,因此保留在缓冲区中。并且tail将继续,直到找到文件末尾,而这对于 永远不会发生/dev/zero。因此您永远不会从 获得任何有用的输出tail /dev/zero

幸运的是,您使用的是 32 位系统,并且有足够的可用内存,因此单个进程可用的内存(通常为 2 GiB,但可能因内核配置而异)很快就会耗尽,并且不会进行交换,因此命令会中止。如果您在可用内存较少或地址空间较大的系统(64 位系统)上尝试相同操作,tail 将占用它能获得的所有内存,让内核尽可能多地进行交换,最终您仍会收到内存分配错误。或者触发 OOM-killer。但标准输出上仍然没有空字节。

相关内容