mmap返回ENOMEM

时间:2017-11-15 10:16:09

标签: c linux mmap

我阅读了与此主题相关的每篇文章,但没有找到能解决问题的任何内容。

我试图映射由底层文件支持的900Mb MAP_SHARED。 我们有2Gb的RAM和2Gb的VIRTUAL MEMORY(1Gb保留给内核+ 1Gb保留给Hypervisor)。

ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);

我在考虑缺少VMEM,所以我试着把#34; sysctl -w vm.overcommit_memory = 1"但它也失败了。

我做了一个小循环(下面)知道mmap真正失败的大小,我发现它接近700Mb,所以它可以正常工作700Mb然后失败。

ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if ((MAP_FAILED == ptr) && (errno == ENOMEM)) {
    for (i = 0; i < 16; i++) {
        ptr = mmap(NULL, size / 16, PROT_READ, MAP_SHARED, fd, (size / 16) * i);
        if (MAP_FAILED == ptr) {
            printf("map num:%d failed errno:%d", i, errno);
            break;
        }
    }

感谢您的帮助。

PS:shm_open和ftruncate没有返回任何错误。 ftruncate和mmap的工作大小相同。

free -m返回Swap 0 0 0。

编辑1: 显然,我发现我在VMEM中没有900Mb的连续空间,就像我说的小mmap,楼梯一般,我能够达到~720Mo的mmap但是我没有找到一个关于这个连续限制的解决方法。我是否必须将其拆分为多个文件描述符或类似的内容?

编辑2:

随着一些shmem尺寸的改进我现在能够mmap(870Mb),几乎在那里:D 但是我不明白为什么在堆和第一个库之间有 大约880Mb 的巨大差距,有人有提示吗?

在proc / $ PID / maps

的结果下面
08048000-08081000 r-xp 00000000 08:02 2564       /usr/bin/myapp
08081000-0820a000 rw-p 00038000 08:02 2564       /usr/bin/myapp
0820a000-09151000 rwxp 00000000 00:00 0          [heap]
40000000-40022000 r-xp 00000000 08:02 14697      /lib/ld-2.22.so
40022000-40023000 r--p 00021000 08:02 14697      /lib/ld-2.22.so
40023000-40024000 rw-p 00022000 08:02 14697      /lib/ld-2.22.so
40024000-40025000 rw-p 00000000 00:00 0 
40027000-40040000 r-xp 00000000 08:02 14692      /lib/libpthread-2.22.so
40040000-40041000 r--p 00018000 08:02 14692      /lib/libpthread-2.22.so
40041000-40042000 rw-p 00019000 08:02 14692      /lib/libpthread-2.22.so
40042000-40044000 rw-p 00000000 00:00 0 
40044000-4004b000 r-xp 00000000 08:02 14686      /lib/librt-2.22.so
4004b000-4004c000 r--p 00006000 08:02 14686      /lib/librt-2.22.so
4004c000-4004d000 rw-p 00007000 08:02 14686      /lib/librt-2.22.so
4004d000-401b2000 r-xp 00000000 08:02 39034      /usr/lib/libxml2.so.2.9.2
401b2000-401b7000 rw-p 00164000 08:02 39034      /usr/lib/libxml2.so.2.9.2
401b7000-401b8000 rw-p 00000000 00:00 0 
401b8000-40368000 r-xp 00000000 08:02 14699      /lib/libc-2.22.so
40368000-40369000 ---p 001b0000 08:02 14699      /lib/libc-2.22.so
40369000-4036b000 r--p 001b0000 08:02 14699      /lib/libc-2.22.so
4036b000-4036c000 rw-p 001b2000 08:02 14699      /lib/libc-2.22.so
4036c000-4036f000 rw-p 00000000 00:00 0 
4036f000-40372000 r-xp 00000000 08:02 14881      /lib/libdl-2.22.so
40372000-40373000 r--p 00002000 08:02 14881      /lib/libdl-2.22.so
40373000-40374000 rw-p 00003000 08:02 14881      /lib/libdl-2.22.so
40374000-40375000 rw-p 00000000 00:00 0 
40375000-4038a000 r-xp 00000000 08:02 14698      /lib/libz.so.1.2.8
4038a000-4038b000 rw-p 00015000 08:02 14698      /lib/libz.so.1.2.8
4038b000-403d6000 r-xp 00000000 08:02 14664      /lib/libm-2.22.so
403d6000-403d7000 r--p 0004a000 08:02 14664      /lib/libm-2.22.so
403d7000-403d8000 rw-p 0004b000 08:02 14664      /lib/libm-2.22.so
403d8000-403da000 rw-p 00000000 00:00 0 
403da000-40b6a000 rw-s 17180000 00:05 2845       /dev/vmfileshm20
40b6a000-40b6b000 ---p 00000000 00:00 0 
40b6b000-4136b000 rw-p 00000000 00:00 0 
4136b000-4156c000 rw-s 17a00000 00:05 2758       /dev/vmfileshm12
4156c000-4176d000 rw-s 17c80000 00:05 2801       /dev/vmfileshm16
4176d000-4176e000 ---p 00000000 00:00 0 
4176e000-41f6e000 rw-p 00000000 00:00 0 
41f6e000-42e6f000 rw-s 17f00000 00:05 2670       /dev/vmfileshm4
42f00000-42f21000 rw-p 00000000 00:00 0 
42f21000-43000000 ---p 00000000 00:00 0 
43000000-43021000 rw-p 00000000 00:00 0 
43021000-43100000 ---p 00000000 00:00 0 
43100000-44001000 rw-s 1ad80000 00:05 2713       /dev/vmfileshm8
44001000-44002000 ---p 00000000 00:00 0 
44002000-44802000 rw-p 00000000 00:00 0 
44802000-449ff000 rw-s 1d300000 00:05 2890       /dev/vmfileshm24
449ff000-44a00000 ---p 00000000 00:00 0 
44a00000-45200000 rw-p 00000000 00:00 0 
45200000-45201000 ---p 00000000 00:00 0 
45201000-45a01000 rw-p 00000000 00:00 0 
45a01000-47570000 rw-s 1d780000 00:05 2933       /dev/vmfileshm28
47570000-47aef000 rw-s 28380000 00:05 2967       /dev/vmfileshm31
47aef000-47af0000 ---p 00000000 00:00 0 
47af0000-482f0000 rw-p 00000000 00:00 0 
482f0000-490e1000 r--s 2c480000 00:05 3025       /dev/vmfileshm37
490e1000-49ed2000 r--s 2c480000 00:05 3025       /dev/vmfileshm37
49ed2000-4acc3000 r--s 2c481000 00:05 3025       /dev/vmfileshm37
4acc3000-4bab4000 r--s 2c482000 00:05 3025       /dev/vmfileshm37
4bab4000-4c8a5000 r--s 2c483000 00:05 3025       /dev/vmfileshm37
4c8a5000-4d696000 r--s 2c484000 00:05 3025       /dev/vmfileshm37
4d696000-4e487000 r--s 2c485000 00:05 3025       /dev/vmfileshm37
4e487000-4f278000 r--s 2c486000 00:05 3025       /dev/vmfileshm37
4f278000-50069000 r--s 2c486000 00:05 3025       /dev/vmfileshm37
50069000-50e5a000 r--s 2c487000 00:05 3025       /dev/vmfileshm37
50e5a000-51c4b000 r--s 2c488000 00:05 3025       /dev/vmfileshm37
51c4b000-52a3c000 r--s 2c489000 00:05 3025       /dev/vmfileshm37
52a3c000-5382d000 r--s 2c48a000 00:05 3025       /dev/vmfileshm37
5382d000-5461e000 r--s 2c48b000 00:05 3025       /dev/vmfileshm37
5461e000-5540f000 r--s 2c48c000 00:05 3025       /dev/vmfileshm37
5540f000-56200000 r--s 2c48d000 00:05 3025       /dev/vmfileshm37
56200000-56ff1000 r--s 2c48d000 00:05 3025       /dev/vmfileshm37
56ff1000-57de2000 r--s 2c48e000 00:05 3025       /dev/vmfileshm37
57de2000-58bd3000 r--s 2c48f000 00:05 3025       /dev/vmfileshm37
58bd3000-599c4000 r--s 2c490000 00:05 3025       /dev/vmfileshm37
599c4000-5a7b5000 r--s 2c491000 00:05 3025       /dev/vmfileshm37
5a7b5000-5b5a6000 r--s 2c492000 00:05 3025       /dev/vmfileshm37
5b5a6000-5c397000 r--s 2c493000 00:05 3025       /dev/vmfileshm37
5c397000-5d188000 r--s 2c494000 00:05 3025       /dev/vmfileshm37
5d188000-5df79000 r--s 2c494000 00:05 3025       /dev/vmfileshm37
5df79000-5ed6a000 r--s 2c495000 00:05 3025       /dev/vmfileshm37
5ed6a000-5fb5b000 r--s 2c496000 00:05 3025       /dev/vmfileshm37
5fb5b000-6094c000 r--s 2c497000 00:05 3025       /dev/vmfileshm37
6094c000-6173d000 r--s 2c498000 00:05 3025       /dev/vmfileshm37
6173d000-6252e000 r--s 2c499000 00:05 3025       /dev/vmfileshm37
6252e000-6331f000 r--s 2c49a000 00:05 3025       /dev/vmfileshm37
6331f000-64110000 r--s 2c49b000 00:05 3025       /dev/vmfileshm37
64110000-64f01000 r--s 2c49b000 00:05 3025       /dev/vmfileshm37
64f01000-65cf2000 r--s 2c49c000 00:05 3025       /dev/vmfileshm37
65cf2000-66ae3000 r--s 2c49d000 00:05 3025       /dev/vmfileshm37
66ae3000-678d4000 r--s 2c49e000 00:05 3025       /dev/vmfileshm37
678d4000-686c5000 r--s 2c49f000 00:05 3025       /dev/vmfileshm37
686c5000-694b6000 r--s 2c4a0000 00:05 3025       /dev/vmfileshm37
694b6000-6a2a7000 r--s 2c4a1000 00:05 3025       /dev/vmfileshm37
6a2a7000-6b098000 r--s 2c4a1000 00:05 3025       /dev/vmfileshm37
6b098000-6be89000 r--s 2c4a2000 00:05 3025       /dev/vmfileshm37
6be89000-6cc7a000 r--s 2c4a3000 00:05 3025       /dev/vmfileshm37
6cc7a000-6da6b000 r--s 2c4a4000 00:05 3025       /dev/vmfileshm37
6da6b000-6e85c000 r--s 2c4a5000 00:05 3025       /dev/vmfileshm37
6e85c000-6f64d000 r--s 2c4a6000 00:05 3025       /dev/vmfileshm37
6f64d000-7043e000 r--s 2c4a7000 00:05 3025       /dev/vmfileshm37
7043e000-7122f000 r--s 2c4a8000 00:05 3025       /dev/vmfileshm37
7122f000-72020000 r--s 2c4a8000 00:05 3025       /dev/vmfileshm37
72020000-72e11000 r--s 2c4a9000 00:05 3025       /dev/vmfileshm37
72e11000-73c02000 r--s 2c4aa000 00:05 3025       /dev/vmfileshm37
73c02000-749f3000 r--s 2c4ab000 00:05 3025       /dev/vmfileshm37
749f3000-757e4000 r--s 2c4ac000 00:05 3025       /dev/vmfileshm37
757e4000-765d5000 r--s 2c4ad000 00:05 3025       /dev/vmfileshm37
765d5000-773c6000 r--s 2c4ae000 00:05 3025       /dev/vmfileshm37
773c6000-781b7000 r--s 2c4af000 00:05 3025       /dev/vmfileshm37
781b7000-78fa8000 r--s 2c4af000 00:05 3025       /dev/vmfileshm37
78fa8000-79d99000 r--s 2c4b0000 00:05 3025       /dev/vmfileshm37
79d99000-7ab8a000 r--s 2c4b1000 00:05 3025       /dev/vmfileshm37
7ab8a000-7b97b000 r--s 2c4b2000 00:05 3025       /dev/vmfileshm37
7b97b000-7c76c000 r--s 2c4b3000 00:05 3025       /dev/vmfileshm37
7c76c000-7d55d000 r--s 2c4b4000 00:05 3025       /dev/vmfileshm37
7d55d000-7e34e000 r--s 2c4b5000 00:05 3025       /dev/vmfileshm37
7e34e000-7f13f000 r--s 2c4b6000 00:05 3025       /dev/vmfileshm37
7f91e000-7f93f000 rw-p 00000000 00:00 0          [stack]
00000000-00000000 r-xp 00000000 00:00 0          [vdso]

编辑3: 现在我已经在堆之后移动了所有的小共享内存(见下文),并将> 900Mb放在lib之上(为了获得我的大共享内存的最大可用空间)

08048000-08081000 r-xp 00000000 08:02 2652       /usr/bin/myapp
08081000-0820a000 rw-p 00038000 08:02 2652       /usr/bin/myapp
0820a000-09151000 rwxp 00000000 00:00 0          [heap]
0b001000-0b791000 rw-s 17180000 00:05 2655       /dev/shm20
0b791000-0b992000 rw-s 17a00000 00:05 2567       /dev/shm12
0b992000-0bb93000 rw-s 17c80000 00:05 2611       /dev/shm16
0bb93000-0ca94000 rw-s 17f00000 00:05 2479       /dev/shm4
0ca94000-0d995000 rw-s 19e00000 00:05 2523       /dev/shm8
0d995000-0db92000 rw-s 1ad80000 00:05 2700       /dev/shm24
0db92000-0f701000 rw-s 1b680000 00:05 2743       /dev/shm28
0f701000-0fc80000 rw-s 1eb80000 00:05 2776       /dev/shm31
40000000-40022000 r-xp 00000000 08:02 14697      /lib/ld-2.22.so
40022000-40023000 r--p 00021000 08:02 14697      /lib/ld-2.22.so
40023000-40024000 rw-p 00022000 08:02 14697      /lib/ld-2.22.so
40024000-40025000 rw-p 00000000 00:00 0 
40027000-40040000 r-xp 00000000 08:02 14692      /lib/libpthread-2.22.so
40040000-40041000 r--p 00018000 08:02 14692      /lib/libpthread-2.22.so
40041000-40042000 rw-p 00019000 08:02 14692      /lib/libpthread-2.22.so
40042000-40044000 rw-p 00000000 00:00 0 
40044000-4004b000 r-xp 00000000 08:02 14686      /lib/librt-2.22.so
4004b000-4004c000 r--p 00006000 08:02 14686      /lib/librt-2.22.so
4004c000-4004d000 rw-p 00007000 08:02 14686      /lib/librt-2.22.so
4004d000-401b2000 r-xp 00000000 08:02 39031      /usr/lib/libxml2.so.2.9.2
401b2000-401b7000 rw-p 00164000 08:02 39031      /usr/lib/libxml2.so.2.9.2
401b7000-401b8000 rw-p 00000000 00:00 0 
401b8000-40368000 r-xp 00000000 08:02 14699      /lib/libc-2.22.so
40368000-40369000 ---p 001b0000 08:02 14699      /lib/libc-2.22.so
40369000-4036b000 r--p 001b0000 08:02 14699      /lib/libc-2.22.so
4036b000-4036c000 rw-p 001b2000 08:02 14699      /lib/libc-2.22.so
4036c000-4036f000 rw-p 00000000 00:00 0 
4036f000-40372000 r-xp 00000000 08:02 14881      /lib/libdl-2.22.so
40372000-40373000 r--p 00002000 08:02 14881      /lib/libdl-2.22.so
40373000-40374000 rw-p 00003000 08:02 14881      /lib/libdl-2.22.so
40374000-40375000 rw-p 00000000 00:00 0 
40375000-4038a000 r-xp 00000000 08:02 14698      /lib/libz.so.1.2.8
4038a000-4038b000 rw-p 00015000 08:02 14698      /lib/libz.so.1.2.8
4038b000-403d6000 r-xp 00000000 08:02 14664      /lib/libm-2.22.so
403d6000-403d7000 r--p 0004a000 08:02 14664      /lib/libm-2.22.so
403d7000-403d8000 rw-p 0004b000 08:02 14664      /lib/libm-2.22.so
403d8000-403da000 rw-p 00000000 00:00 0 
403da000-403db000 ---p 00000000 00:00 0 
403db000-40bdb000 rw-p 00000000 00:00 0 
40bdb000-40bdc000 ---p 00000000 00:00 0 
40bdc000-413dc000 rw-p 00000000 00:00 0 
41400000-41421000 rw-p 00000000 00:00 0 
41421000-41500000 ---p 00000000 00:00 0 
41500000-41521000 rw-p 00000000 00:00 0 
41521000-41600000 ---p 00000000 00:00 0 
41600000-41601000 ---p 00000000 00:00 0 
41601000-41e01000 rw-p 00000000 00:00 0 
41e01000-41e02000 ---p 00000000 00:00 0 
41e02000-42602000 rw-p 00000000 00:00 0 
42602000-42603000 ---p 00000000 00:00 0 
42603000-42e03000 rw-p 00000000 00:00 0 
42e03000-42e04000 ---p 00000000 00:00 0 
42e04000-43604000 rw-p 00000000 00:00 0 
43604000-47065000 r--s 22280000 00:05 2835       /dev/shm37
47065000-4aac6000 r--s 22283000 00:05 2835       /dev/shm37
4aac6000-4e527000 r--s 22287000 00:05 2835       /dev/shm37
4e527000-51f88000 r--s 2228a000 00:05 2835       /dev/shm37
51f88000-559e9000 r--s 2228e000 00:05 2835       /dev/shm37
559e9000-5944a000 r--s 22292000 00:05 2835       /dev/shm37
5944a000-5ceab000 r--s 22295000 00:05 2835       /dev/shm37
5ceab000-6090c000 r--s 22299000 00:05 2835       /dev/shm37
6090c000-6436d000 r--s 2229d000 00:05 2835       /dev/shm37
6436d000-67dce000 r--s 222a0000 00:05 2835       /dev/shm37
67dce000-6b82f000 r--s 222a4000 00:05 2835       /dev/shm37
6b82f000-6f290000 r--s 222a8000 00:05 2835       /dev/shm37
6f290000-72cf1000 r--s 222ab000 00:05 2835       /dev/shm37
72cf1000-76752000 r--s 222af000 00:05 2835       /dev/shm37
76752000-7a1b3000 r--s 222b3000 00:05 2835       /dev/shm37
7a1b3000-7dc14000 r--s 222b6000 00:05 2835       /dev/shm37
7ff25000-7ff46000 rw-p 00000000 00:00 0          [stack]
00000000-00000000 r-xp 00000000 00:00 0          [vdso]

由于mmap继续因ENOMEM错误而失败,即使它有足够的地方来映射它,我决定将mmap分块。

for (i = 0; ((i < NB_CHUNK) && (ptr != MAP_FAILED)); i++) {
              ptr = mmap(NULL,
                         ALIGN_ON_PAGE_SIZE((BIG_SIZE / NB_CHUNK)),
                         PROT_READ,
                         MAP_SHARED,
                         fd,
                         (off_t)ALIGN_ON_PAGE_SIZE((BIG_SIZE / NB_CHUNK) * i));
}

现在我没有更多的ENOMEM错误,而且mmap表现不错,但是当我尝试读取其中的值时,我只读取了零内存。

问题是,我可以用这种方式填充mmap吗?

1 个答案:

答案 0 :(得分:0)

也许您应该在运行进程时查看/ proc / / limits,找到“最大地址空间”行,并查看其“软限制”列。 mmap将导致ENOMEM的地址空间有限。对于这种情况,您可以在程序中调用setrlimit(2)来修改进程的最大地址空间。

例如:

// set maximum size of the virtual address space to 1GiB
struct rlimit rlim;
rlim_t max_mem = 1 << 30;
rlim.rlim_cur = max_mem;
setrlimit(RLIMIT_AS, &rlim);