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

没有错误

最佳答案

区别是:
使用MEM_RESERVE,您基本上是在对操作系统说:“嘿,请,我需要这个连续的虚拟内存页面块,您能给我一个适合我需要的内存地址吗?”

然后,操作系统会计算将块保留在何处。
但是它不会分配任何东西。
(要了解操作系统如何做到这一点,只需看一下Mark Russinovich的“Windows Internals 5th”之类的书-提示:在Google上搜索有关VAD Trees的信息)。

因此,当您保留一块内存时,操作系统会简单地在树上某处或类似的结构上分配一个“节点”,说这些地址是保留的,就像餐厅的 table 一样,不能被保留。在对VirtualAlloc()的其他调用中使用。

相反,当您实际使用MEM_COMMIT提交页面时,操作系统实际上是在您之前保留的块上分配虚拟内存页面。
当然,您只能在之前保留的块上提交页面。
不这样做就是像在餐厅预订座位,然后在您未预定的另一张 table 上坐下来。

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

注意2:您可以使用或MEM_RESERVE|MEM_COMMIT只是一个有用的事实,因此您不必两次调用VirtualAlloc()API,但实际上它们仍然是两个非常不同的操作。

注意3:MEM_COMMIT标志将在页面大小边界上提交页面,而使用MEM_RESERVEMEM_RESERVE|MEM_COMMIT将在大于页面大小的边界上保留或保留+提交页面,从今天开始,在所有Windows版本上通常为64K。您可以通过调用GetSystemInfo()获得此号码。

10-07 22:24