我一直在使用openSUSE 11.2 x86_64上的大型稀疏文件.当我尝试mmap()1TB稀疏文件,它失败与ENOMEM.我本来以为64位地址空间足以映射到太字节,但似乎没有.进一步的实验,1GB的文件工作正常,但是2GB的文件(还有更大的)失败.我猜想可能会有一个设置在某处进行调整,但广泛的搜索没有变化.
#include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/types.h> #include <unistd.h> int main(int argc,char *argv[]) { char * filename = argv[1]; int fd; off_t size = 1UL << 40; // 30 == 1GB,40 == 1TB fd = open(filename,O_RDWR | O_CREAT | O_TRUNC,0666); ftruncate(fd,size); printf("Created %ld byte sparse file\n",size); char * buffer = (char *)mmap(NULL,(size_t)size,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0); if ( buffer == MAP_Failed ) { perror("mmap"); exit(1); } printf("Done mmap - returned 0x0%lx\n",(unsigned long)buffer); strcpy( buffer,"cafebabe" ); printf("Wrote to start\n"); strcpy( buffer + (size - 9),"deadbeef" ); printf("Wrote to end\n"); if ( munmap(buffer,(size_t)size) < 0 ) { perror("munmap"); exit(1); } close(fd); return 0; }
解决方法
问题是每个进程的虚拟内存限制设置为只有1.7GB. ulimit -v 1610612736将其设置为1.5TB,并且我的mmap()调用成功.谢谢,bmargulies,提示尝试ulimit -a!