为什么在32位armv7l上mmap 4GB文件成功了?

时间:2016-05-24 09:18:02

标签: c++ memory mmap

我从mmap(2)手册页和搜索结果中得到了印象,mmap仅限于系统的可用地址空间,减去系统保留的地址空间。所以在32位armv7l上,我假设它大约3GB =(4GB - 1GB)。

但似乎我实际上可以mmap一个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, MAP_FAILED: 0, Status: Success
PA: 0x30714000, MAP_FAILED: 0, Status: Success
PA: 0x3ade000, MAP_FAILED: 0, Status: Success
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory

从结果来看,mmap成功了4次才真正陷入困境。但它不应该成功,因为文件大约是5GB。

我的问题是:

  1. mmap
  2. 需要这种行为吗?
  3. 如果没有,我哪里做错了?
  4. 编辑:

      

    使用物理地址扩展(PAE),32位系统可以添加超过2 ^ 32个字节(如果可用)。

    此CPU没有PAE支持

    $> 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
    

1 个答案:

答案 0 :(得分:8)

PAE无关紧要。这与访问大量物理内存无关。

问题是您的mmap函数对映射的大小采用32位值。因此,您的64位大小会被截断,实际上您实际分配的虚拟内存不到1 GB。