It seems that every process has private memory mappings that are neither readable nor writeable nor executable (whose flags are "—p"):
grep -- --- /proc/self/maps
7f2bd9bf7000-7f2bd9df6000 ---p 001be000 fc:00 3733 /lib/x86_64-linux-gnu/libc-2.19.so
7f2bd9e04000-7f2bda003000 ---p 00003000 fc:00 3743 /lib/x86_64-linux-gnu/libdl-2.19.so
7f2bda042000-7f2bda241000 ---p 0003d000 fc:00 36067 /lib/x86_64-linux-gnu/libpcre.so.3.13.1
returns some in shared libraries and doing that for java (JVM) processes even returns a dozen of anonymous mappings with hundreds of megabytes.
Edit: If these mappings are placeholders, who will be using these kept places at which events and from which other activity are they protected – in other words: What is the wrong behavior that could happen if these placeholders were not there ?
2nd edit: Given these holes in shared libraries are in fact helpful for some purpose of the compiler and/or dynamic linker, there must be some other purpose for these holes in anonymous mappings visible in JVM processes. Sorted the anonymous mappings of a tomcat JVM process by size:
20 MB 00007FA0AAB52000-00007FA0AC000000 ---p 00000000 00:00 0
41 MB 00007FA0B1603000-00007FA0B4000000 ---p 00000000 00:00 0
50 MB 00007FA090D04000-00007FA094000000 ---p 00000000 00:00 0
53 MB 00007FA0F8A40000-00007FA0FC000000 ---p 00000000 00:00 0
61 MB 00007FA0C42C5000-00007FA0C8000000 ---p 00000000 00:00 0
61 MB 00007FA0CC29A000-00007FA0D0000000 ---p 00000000 00:00 0
61 MB 00007FA0D0293000-00007FA0D4000000 ---p 00000000 00:00 0
62 MB 00007FA0D814C000-00007FA0DC000000 ---p 00000000 00:00 0
62 MB 00007FA0E017E000-00007FA0E4000000 ---p 00000000 00:00 0
63 MB 00007FA0B803B000-00007FA0BC000000 ---p 00000000 00:00 0
63 MB 00007FA0BC021000-00007FA0C0000000 ---p 00000000 00:00 0
63 MB 00007FA0C0021000-00007FA0C4000000 ---p 00000000 00:00 0
63 MB 00007FA0D4075000-00007FA0D8000000 ---p 00000000 00:00 0
63 MB 00007FA0DC040000-00007FA0E0000000 ---p 00000000 00:00 0
63 MB 00007FA0E4067000-00007FA0E8000000 ---p 00000000 00:00 0
189 MB 00007FA0EC300000-00007FA0F8000000 ---p 00000000 00:00 0
1008 MB 0000000100FF5000-0000000140000000 ---p 00000000 00:00 0
Best Answer
http://www.cs.stevens.edu/~jschauma/810/elf.html
It's also easy to see this happening as a
mprotect
call, using strace e.g.strace -f grep -- . /proc/self/maps 2>&1 |less
.There are mirrors of the glibc repo on github, so it wasn't hard to search for PROT_NONE...
https://github.com/bminor/glibc/blob/73dfd088936b9237599e4ab737c7ae2ea7d710e1/elf/dl-map-segments.h#L21
https://github.com/bminor/glibc/blob/73dfd088936b9237599e4ab737c7ae2ea7d710e1/elf/dl-unmap-segments.h#L25
Java
The natural assumption is that it wishes to have contiguous heap memory for some reason.
It uses PROT_NONE to reserve space, until it actually needs it. The original context of this comment is a discussion about Linux VM overcommit: using unaccessible mappings avoids requiring any commitment from the kernel (until the mapping is needed & made accessible), in case the kernel is configure for strict commit mode.
If you're wondering why it needs to make this reservation in advance in the context of the JVM, consider that native code linked in using JNI or equivalent might also be using mmap.
https://lwn.net/Articles/627728/