7

我对 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);

第二种选择有什么好处?

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

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

没有错误

4

1 回答 1

13

不同之处在于: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()

于 2015-07-23T11:08:58.480 回答