Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VirtualAlloc MEM_COMMIT and MEM_RESERVE

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

like image 251
user2714997 Avatar asked Sep 25 '14 02:09

user2714997


People also ask

What is Mem_commit?

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() .

What is VirtualAlloc?

The VirtualAlloc function can be used to reserve an Address Windowing Extensions (AWE) region of memory within the virtual address space of a specified process. This region of memory can then be used to map physical pages into and out of virtual memory as required by the application.

Why use VirtualAlloc?

With VirtualAlloc you can reserve 1gb address range. Later you can commit parts of it on demand - so that to given chunks of reserved addresses are assigned actual physical memory blocks. Reservation should never fail, while commit might fail if physical memory is short.

Which API call is in charge of allocating memory in a remote process?

VirtualAlloc Ex is what one process can use to allocate memory in an address space of a different process.


1 Answers

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().

like image 69
Marco Pagliaricci Avatar answered Oct 16 '22 09:10

Marco Pagliaricci