当尝试使用写时复制语义(PROT_READ | PROT_WRITE 和 MAP_PRIVATE)映射 5GB 文件时,会在 2.6.26-2-amd64 Linux 内核上发生这种情况。映射小于 4GB 的文件或仅使用 PROT_READ 可以正常工作。这不是本问题中报告的软资源限制问题;虚拟限制大小是无限的。
这是重现问题的代码(实际代码是Boost.Interprocess的一部分)。
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
main()
{
struct stat b;
void *base;
int fd = open("foo.bin", O_RDWR);
fstat(fd, &b);
base = mmap(0, b.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (base == MAP_FAILED) {
perror("mmap");
return 1;
}
return 0;
}
这就是发生的事情:
dd if=/dev/zero of=foo.bin bs=1M seek=5000 count=1
./test-mmap
mmap: Cannot allocate memory
这是相关的 strace (新编译的 4.5.20)输出,正如 nos 所要求的那样。
open("foo.bin", O_RDWR) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=5243928576, ...}) = 0
mmap(NULL, 5243928576, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = -1 ENOMEM (Cannot allocate memory)
dup(2) = 4
[...]
write(4, "mmap: Cannot allocate memory\n", 29mmap: Cannot allocate memory
) = 29