5

I have an application that reserves a contiguous memory block using VirtualAllocEx on Windows with the MEM_RESERVE flag. This reserves a virtual memory block, but does not back it with a physical page or page file chunk. Hence, accessing the allocated memory will result in a segmentation fault -- but other allocations will not intersect with this virtual memory block.

How can I do the same for Linux with mmap? I did notice the answer in this question, but does that really guarantee that say, 1 GB of physical memory won't be allocated to my process if I don't touch the allocated pages? I don't want any thrashing problems.

Community
  • 1
  • 1
Matt Fichman
  • 5,458
  • 4
  • 39
  • 59

1 Answers1

10

I believe you should be able to achieve the same by mapping anonymous memory with PROT_NONE. Accessing PROT_NONE memory will result in a segfault, but the memory region will be reserved and not used for any other purpose. If you want to allocate a very big chunk of memory, add MAP_NORESERVE to ensure that the default overcommit mechanism won't check your allocation.

PROT_NONE is commonly employed for "guard" pages at the end of stacks.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • This is a very interesting technique. By using `mmap(2)` + `PROT_NONE` you basically have the same effects of `VirtualAlloc()` + `MEM_RESERVE` on Windows. I am a little bit more concerned about the `MAP_NORESERVE` flag: while you can set `PROT_READ|PROT_WRITE` with `mprotect(2)` once you need pages (that will be like a call to `VirtualAlloc()`+`MEM_COMMIT`), it seems you cannot reset the flag `MAP_NORESERVE` once you've specified it to a call to `mmap(2)`, so your memory will be set as "no reserve" forever, even when "committed". How would you solve this quirk? – Marco Pagliaricci Jul 28 '15 at 11:10
  • 1
    I think the cleanest solution would be to call mmap again with `MAP_FIXED` and the address/size of the region to allocate/commit. It’s entirely possible to mmap on top of existing regions (replacing any existing mapping in the area) if you use `MAP_FIXED`, and this is a common way of changing mmap flags that can’t be changed via some combination of mlock/mprotect. – nneonneo Feb 11 '21 at 05:01