我对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;
}
没有错误
答案 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_RESERVE
或MEM_RESERVE|MEM_COMMIT
将在大于页面大小的边界上保留或保留+提交页面,从今天开始,所有版本的Windows通常都是64K。您可以致电GetSystemInfo()
来获取此号码。