VirtualAlloc MEM_COMMIT和MEM_RESERVE

时间:2014-09-25 02:09:09

标签: memory virtualalloc

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

没有错误

1 个答案:

答案 0 :(得分:6)

区别在于: 与MEM_RESERVE你基本上对操作系统说:“嘿,拜托,我需要这个连续的虚拟内存页块,你能给我一个符合我需求的内存地址吗?”

操作系统会计算保留块的位置。 但它还没有分配任何东西。 (要了解操作系统是如何做到这一点的,请查看Mark Russinovich撰写的“Windows Internals 5th”等书籍 - 提示:在Google上搜索VAD Trees)。

所以,当你保留一块内存时,操作系统只会在某个地方的树上分配一个“节点”,或者像这样的结构,说这些地址是保留的,就像在餐厅的桌子一样,不能用于VirtualAlloc()的其他调用。

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

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

注意2:OR MEM_RESERVE|MEM_COMMIT这个事实只是一个有用的事实,所以你不必两次调用`VirtualAlloc()'API,但事实上它们仍然是两个非常不同的操作。 / p>

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

相关问题