Marco Pagliaricci
Marco Pagliaricci

Reputation: 1386

Is the `MEM_RESERVE` flag of `VirtualAlloc()` really useful today?

First of all, let me say that I very well know how VirtualAlloc() works and how virtual memory facilities of the modern operating systems, in general, work.

Said that, using the MAP_RESERVE flag of the VirtualAlloc() Windows API, without using also MEM_COMMIT, has some practical use today?

I mean, when I call VirtualAlloc() with MEM_RESERVE|MEM_COMMMIT I both reserve and commit pages, but I know that the operating system will really allocate pages only when I try to write into them. This optimization happens on practically all the modern operating systems.

So, with this optimization in mind, if I call VirtualAlloc() with MEM_RESERVE and then I call it several times with MEM_COMMIT to commit pages, isn't the same result of calling VirtualAlloc() only once, specifying MEM_RESERVE|MEM_COMMIT ?

Since specifying only MEM_RESERVE will only reserve pages boundary addresses, without committing real pages, but then MEM_RESERVE|MEM_COMMIT will reserve+commit only pages I write to, isn't using MEM_RESERVE alone, a waste of time today? With only 1 call to VirtualAlloc() with MEM_RESERVE|MEM_COMMIT I can basically obtain the same result of calling VirtualAlloc() 1 time with MEM_RESERVE and calling it several N times with MEM_COMMIT.

As a proof of what I am saying, I have noticed that the MEM_RESERVE facility doesn't exist at all in Unices/POSIX systems which use the mmap(2) syscall. Also there you can "commit" a big chunk of pages calling mmap(2) once, and then the pages will be really allocated only when you write into them, all optimized by the operating system.

So, is using MEM_RESERVE alone just an old days thing useful only when memory pages were a precious resource, and so today is useless? Or, using this flag alone (and then calling VirtualAlloc() N times with MEM_COMMIT) still has some practical use that I am missing?

Upvotes: 8

Views: 1897

Answers (2)

When you commit memory, the memory manager doesn't immediately allocate real pages for you, but it does count them towards the total number available. The memory manager will never commit more pages than actually exist, and you are guaranteed that when you access a committed page, the memory is there.

MEM_RESERVE's purpose is to allocate virtual memory addresses. You can reserve as much address space as you want, up to many terabytes on 64-bit systems, even if you don't have many terabytes of actual space.

By default, Linux doesn't limit allocations to the amount of actual space available. This "feature" is called overcommit. That means that on Linux there are no separate reserve and commit steps. If you want to reserve address space on Linux, another question recommends mmapping an area with no permissions..

Upvotes: 10

Dmitry Shesterkin
Dmitry Shesterkin

Reputation: 360

In addition to the previous answer here is a quote from Microsoft docs:

As an alternative to dynamic allocation, the process can simply commit the entire region instead of only reserving it. Both methods result in the same physical memory usage because committed pages do not consume any physical storage until they are first accessed. The advantage of dynamic allocation is that it minimizes the total number of committed pages on the system. For very large allocations, pre-committing an entire allocation can cause the system to run out of committable pages, resulting in virtual memory allocation failures.

Upvotes: 3

Related Questions