2014-09-25 86 views
4

我对小的VirtualAlloc混淆,的VirtualAlloc MEM_COMMIT和MEM_RESERVE

我们可以保留内存使用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); 

什么是选择第二的benfit

我可以使用下面的功能得到缓冲:

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

没有错误

+1

因为第一个在技术上是不正确的。你不能提交没有保留。 – 2014-09-25 05:59:01

+0

但我可以使用下面的函数来分配缓冲区,如下所示: void * pdata = VirtualAlloc(NULL,64 * 1024 * 1024,MEM_COMMIT,PAGE_READWRITE); if(pdata == NULL) cout <<“Last error is”<< GetLastError()<< endl; } – user2714997 2014-09-25 07:18:46

+0

操作系统可以猜出你的意思。所以没有区别。 – 2014-09-25 08:18:46

回答

5

的区别是: 与MEM_RESERVE你基本上说的操作系统:“喂,拜托,我需要的虚拟内存页面的这个连续的块,你能不能给我一个记忆符合我需求的地址?“

并且操作系统计算你的块的保留位置。 但它不会分配任何东西。 (要了解操作系统如何执行此操作,只需查看Mark Russinovich撰写的“Windows Internals 5th”等书籍 - 提示:在Google上搜索有关VAD Trees的信息)。因此,当您保留一块内存时,操作系统将简单地在树上或某个类似的结构上分配一个“节点”,并说这些地址是保留的,就像餐厅的一张桌子一样,并且不能用于VirtualAlloc()的其他调用。

实际上,当您实际上承诺页面为MEM_COMMIT时,操作系统实际上是在您之前保留的块上分配虚拟内存页面。 当然,您可以仅在您之前保留的块上提交页面。 不这样做就像预订坐在餐厅,然后坐在另一张桌子,而不是你保留。

注意:由于您在其上读/写(软页面错误),因此实际上并未分配页面也不提交它们。这是一个非常有用的优化。注意2:事实上,你可以或者MEM_RESERVE|MEM_COMMIT只是一些有用的东西,所以你不必调用'VirtualAlloc()'API两次,但实际上它们仍然是两个非常不同的操作。

注3:本MEM_COMMIT标志将提交页面大小边界上的网页,同时使用MEM_RESERVEMEM_RESERVE|MEM_COMMIT将预留或预留+提交上比页面大小,通常在从今天起所有版本的Windows 64K边界更大的页面。你可以拨打GetSystemInfo()得到这个号码。

相关问题