mmap returning ENOMEM

僤鯓⒐⒋嵵緔 提交于 2019-12-11 08:53:03

问题


I read every post linked to this topic and didn't find anything that was able to solve my problem.

I'm trying to map a 900Mb MAP_SHARED backed by an underlying file. We have 2Gb of RAM and only 2Gb of VIRTUAL MEMORY available (1Gb reserved for Kernel + 1Gb reserved for Hypervisor).

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

I was thinking about a lack of VMEM available so I tried to put "sysctl -w vm.overcommit_memory=1" but it failed with this too.

I made a little loop (below) to know at which size mmap is really failing and I found it was next to 700Mb, so it works fine up to 700Mb and then failed.

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;
        }
    }

Thanks for your help.

PS: shm_open and ftruncate are not returning any error. ftruncate and mmap are working with the same size.

free -m is returning Swap 0 0 0.


EDIT 1: Obviously it cames up that I've no 900Mb contiguous space in VMEM, like I said with little mmap, stair by stair, I'm able to reach a mmap of ~720Mo but I didn't find a workaround about this contiguous limitation. Do I have to split it on several file descriptor or something like that ?


EDIT 2:

With some shmem size improvement I'm now able to mmap(870Mb), almost there :D But I don't understand why there is a HUGE GAP of ~880Mb between the heap and the first library, does someone have an hint for me?

Below the result of 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]

EDIT 3: Now I've moved all little shared memories (see below) just after the heap and let the >900Mb one above the lib (in order to have the maximum available space for my big shared mem)

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]

As mmap continued to fail with ENOMEM error even if it got enough place to map it I decided to chunk the 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));
}

Now I've no more ENOMEM error and the mmap is doing well but when I try to read a value in it I'm only reading zeroed memory.

The question is, Can I chunk a mmap this way ?


回答1:


Maybe you should look at /proc/<pid>/limits while running your process, find "Max address space" row and see its "Soft Limit" column. mmap will cause ENOMEM for limited address space. For this situation, you can call setrlimit(2) in your program to modify Max address space of process.

For example:

// 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);


来源:https://stackoverflow.com/questions/47304716/mmap-returning-enomem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!