我对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的信息)。
因此,当您保留一块内存时,操作系统会简单地在树上某处或类似的结构上分配一个“节点”,说这些地址是保留的,就像餐厅的桌子一样,不能被保留。在对VirtualAlloc()
的其他调用中使用。
相反,当您实际使用MEM_COMMIT
提交页面时,操作系统实际上是在之前保留的块上分配虚拟内存页面。
当然,您只能在之前保留的块上提交页面。
不这样做,就像在餐厅预订座位,然后在您未预订的另一张桌子上坐下来。
注意:由于您在页面上进行了读写(软页面错误),因此页面实际上并没有分配提交它们。这是非常有用的优化。
注意2:您可以使用MEM_RESERVE|MEM_COMMIT
或OR的事实只是有用的,因此您不必两次调用VirtualAlloc()API,但实际上它们仍然是两个非常不同的操作。
注意3:MEM_COMMIT
标志将在页面大小边界上提交页面,而使用MEM_RESERVE
或MEM_RESERVE|MEM_COMMIT
将在大于页面大小的边界上保留或保留+提交页面,通常从今天开始在所有Windows版本上为64K 。您可以通过拨打GetSystemInfo()
来获得此号码。