VirtualAlloc MEM_COMMIT and MEM_RESERVE
Asked Answered
P

1

8

I'm little confuse about VirtualAlloc,

We can reserve memory use MEM_RESERVE, and then commit it use MEM_COMMIT, but I'm little confuse about what the difference when use between below two functions:

m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_COMMIT, PAGE_READWRITE);
m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

What‘s the benfit of the second choose?

And I can use below function to get buffer:

void* pdata = VirtualAlloc(NULL, 64*1024*1024, MEM_COMMIT, PAGE_READWRITE);
if (pdata == NULL)
{
    cout<<"Last error is "<<GetLastError()<<endl;
}

There is no error

Prynne answered 25/9, 2014 at 2:9 Comment(5)
Because the first is technically incorrect. You cannot commit without reserving.Vaules
But I can use below function to allocate buffer like below: void* pdata = VirtualAlloc(NULL, 64*1024*1024, MEM_COMMIT, PAGE_READWRITE); if (pdata == NULL) { cout<<"Last error is "<<GetLastError()<<endl; }Prynne
The OS can guess what you meant. So there is no difference.Michaella
But you're supposed to pass both. Don't make the OS cover for your mistakes. Someday the OS may stop being so accommodating of programming errors.Vaules
I see, thanks for your help. Turned out the OS be the good manPrynne
A
14

The difference is this: with MEM_RESERVE you're basically saying to the operating system: "Hey, please, I need this contiguous block of virtual memory pages, can you give me a memory address that fits my needs?"

And the operating system calculates where to reserve your block. But it won't allocating nothing yet. (To see how the operating system does this, just look at books like "Windows Internals 5th" by Mark Russinovich -- hint: search on Google about VAD Trees).

So, when you reserve a block of memory, the operating system will simply allocating a "node" on a tree somewhere, or a structure like that, saying that those addresses are reserved, just like a table at the restaurant, and that cannot be used in other calls to VirtualAlloc().

Instead, when you actually commit pages with MEM_COMMIT, the operating system is actually allocating virtual memory pages on the block you reserved before. Of course, you can commit pages only on blocks you reserved before. Not doing that is like reserving sits on a restaurant, then take a sit in another table, not reserved by you.

NOTE: The pages are actually not allocated with committing them neither, since you read/write on them (soft page fault). This is a very useful optimization.

NOTE2: The fact that you can OR MEM_RESERVE|MEM_COMMIT is just something useful, so you don't have to call the `VirtualAlloc()' API two times, but in fact they remain two very different operations.

NOTE3: The MEM_COMMIT flag will commit pages on a page size boundary, while using MEM_RESERVE or MEM_RESERVE|MEM_COMMIT will reserve or reserve+commit pages on a boundary greater than the page size, usually 64K on all versions of Windows since today. You can get this number by calling GetSystemInfo().

Angelo answered 23/7, 2015 at 11:8 Comment(4)
So MEM_COMMIT can be called alone if I only need a contiguous allocation less or equal than a page size ?Execution
Well, let's say that with VirtualAlloc() you're allocating pages of memory. If you try to allocate < 4096 bytes (or, 1 page), you get allocated 4096 bytes (or, 1 page). The fact that Windows will allocate 64K, it's more an internal thing. You should always think in terms of pages when using VirtualAlloc(), at least it's what I do. Same thing applies with mmap() in Unix.Angelo
What is the point to reserve a memory space without committing it? Said differently: why VirtualAlloc make the reservation visible from the user point of view (considering the memory should be ultimately committed before being accessed and does not cause a prefault)?Jackknife
@JérômeRichard If I got the question, the point of reserve a memory space without committing the actual pages, could be many: you only want to reserve pages without committing the actual physical pages (even if there is the prefault mechanism, you actually don't want allocate phys pages, even if they are not faulted yet), or just memory expansion: reserve could be used for future memory expansion; or reserved memory can be used for file mapping, or memory protection.Angelo

© 2022 - 2024 — McMap. All rights reserved.