这个问题我已经困扰我很久了,我似乎无法解决它,基本上,我的 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
这个问题有点老了,但答案很简单:
tail
ing 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。但标准输出上仍然没有空字节。