A simple program to illustrate the effect of MAP_NORESERVE in mmap.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

static void meminfo() {
system("cat /proc/meminfo | grep Committed_AS");
}

int main() {
// to flush meminfo output
setbuf(stdout, NULL);

size_t one_g = 1024*1024*1024; // 1G
size_t size = 5 * one_g;

{
puts("Without MAP_NORESERVE (i.e. with-reserve)");
puts("Before:");
meminfo();

void* ptr = mmap(NULL, size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
return 1;
}

puts("After:");
meminfo();

munmap(ptr, size);
}

puts("");

{
puts("With MAP_NORESERVE");
puts("Before:");
meminfo();

void* ptr = mmap(NULL, size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
-1, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
return 1;
}

puts("After:");
meminfo();

munmap(ptr, size);
}


return 0;
}

Output on my box:

1
2
3
4
5
6
7
8
9
10
11
Without MAP_NORESERVE (i.e. with-reserve)
Before:
Committed_AS: 14575316 kB
After:
Committed_AS: 19818196 kB

With MAP_NORESERVE
Before:
Committed_AS: 14575448 kB
After:
Committed_AS: 14575316 kB

(The negative naming, NORESERVE, is super confusing, but all in all accounting happens when we reserve.)

ยงReference