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