VirtualAlloc MEM_COMMIT和MEM_RESERVE

use*_*997 5 memory virtualalloc

我对VirtualAlloc感到困惑,

我们可以保留内存使用MEM_RESERVE,然后使用MEM_COMMIT提交它,但是我在下面两个函数之间使用时有点混淆:

m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_COMMIT, PAGE_READWRITE);
m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
Run Code Online (Sandbox Code Playgroud)

第二种选择有什么好处?

我可以使用下面的函数来获取缓冲区:

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

没有错误

Mar*_*cci 7

所不同的是:与MEM_RESERVE你基本上说的操作系统:"喂,拜托,我需要的虚拟内存页面的这个连续的块,你能不能给我,适合我的需求的内存地址?"

操作系统会计算保留块的位置.但它还没有分配任何东西.(要了解操作系统如何执行此操作,请查看Mark Russinovich撰写的"Windows Internals 5th"等书籍 - 提示:在Google上搜索有关VAD树的信息).

因此,当你保留一块内存时,操作系统只会在某个地方的树上分配一个"节点",或者像这样的结构,说这些地址是保留的,就像在餐厅的桌子一样,并且不能用于其他电话VirtualAlloc().

相反,当您实际提交页面时MEM_COMMIT,操作系统实际上是在您之前保留的块上分配虚拟内存页面.当然,您只能在之前保留的块上提交页面.不这样做就像保留坐在餐厅,然后坐在另一张桌子,而不是你保留.

注意:由于您对它们进行读/写(软页错误),因此页面实际上没有分配提交它们.这是一个非常有用的优化.

注意2:你可以使用OR MEM_RESERVE|MEM_COMMIT只是一些有用的事实,所以你不必两次调用`VirtualAlloc()'API,但事实上它们仍然是两个非常不同的操作.

注意3:该MEM_COMMIT标志将在页面大小边界上提交页面,同时使用MEM_RESERVEMEM_RESERVE|MEM_COMMIT将在大于页面大小的边界上保留或保留+提交页面,从今天起在所有Windows版本上通常为64K.您可以致电获取此号码GetSystemInfo().