我从mmap(2)手册页和搜索结果中得到的印象是,mmap仅限于系统的可用地址空间,减去系统保留的地址空间.所以在32位armv7l上,我认为它大约是3GB =(4GB – 1GB).
但似乎我实际上可以毫无问题地映射5 GB文件:
int main(int argc,char** argv) { // stats char * path = argv[1]; struct stat sb; stat(path,&sb); std::cout << "File size: " << sb.st_size << std::endl; // open int fd = open(path,O_RDONLY,S_IRWXU); std::cout << "File descriptor: " << fd << std::endl; int i; for (i =0; i<10; ++i){ void *pa = mmap( nullptr,sb.st_size,PROT_READ,MAP_PRIVATE | MAP_ANONYMOUS,fd,0); std::cout << "PA: " << pa << ",MAP_Failed: " << (pa == MAP_Failed) << ",Status: " << strerror(errno) << std::endl; } }
使用-D_FILE_OFFSET_BITS = 64标志进行编译:
g++ -D_FILE_OFFSET_BITS=64 test.cc
结果产生:
File size: 5045966585 File descriptor: 3 PA: 0x89f80000,MAP_Failed: 0,Status: Success PA: 0x5d34a000,Status: Success PA: 0x30714000,Status: Success PA: 0x3ade000,Status: Success PA: 0xffffffff,MAP_Failed: 1,Status: Cannot allocate memory PA: 0xffffffff,Status: Cannot allocate memory
从结果来看,mmap成功了4次才真正陷入困境.但它不应该成功,因为文件大约是5GB.
我的问题是:
> mmap需要这种行为吗?
>如果没有,我哪里做错了?
编辑:
With physical addres extension (PAE) 32-bit systems can addres much more than 2^32 bytes,if that is available.
$> cat /proc/cpuinfo Processor : ARMv7 Processor rev 4 (v7l) processor : 0 BogoMIPS : 1436.46 processor : 1 BogoMIPS : 1436.46 Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt cpu implementer : 0x41 cpu architecture: 7 cpu variant : 0x0 cpu part : 0xc07 cpu revision : 4 Hardware : sun7i Revision : 0000 Serial : 09c11b9d52544848804857831651664b
解决方法
PAE无关紧要.这不是关于访问大量物理内存.
问题是您的mmap函数采用32位值作为映射的大小.因此,您的64位大小会被截断,而您实际上分配的虚拟内存不到1 GB.