首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VirtualAlloc MEM_COMMIT和MEM_RESERVE

VirtualAlloc MEM_COMMIT和MEM_RESERVE
EN

Stack Overflow用户
提问于 2014-09-25 02:09:08
回答 1查看 6.6K关注 0票数 8

我对VirtualAlloc一点也不困惑,

我们可以保留内存使用MEM_RESERVE,然后使用MEM_COMMIT提交它,但是当使用以下两个函数时,我并不感到困惑:

代码语言:javascript
复制
m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_COMMIT, PAGE_READWRITE);
m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

第二种选择的好处是什么?

我可以使用下面的函数来获得缓冲区:

代码语言:javascript
复制
void* pdata = VirtualAlloc(NULL, 64*1024*1024, MEM_COMMIT, PAGE_READWRITE);
if (pdata == NULL)
{
    cout<<"Last error is "<<GetLastError()<<endl;
}

没有错误

EN

回答 1

Stack Overflow用户

发布于 2015-07-23 11:08:58

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

操作系统计算要在哪里保留块。但它还没有分配任何东西。(要了解操作系统是如何做到这一点的,只需看看的"Windows内部5“之类的书籍--提示:在Google上搜索关于VAD树的内容)。

因此,当您预留一个内存块时,操作系统将简单地在某个树上分配一个“节点”,或者类似这样的结构,表示这些地址是保留的,就像餐厅的一个表,不能用于其他对VirtualAlloc()的调用。

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

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

NOTE2:您可以或MEM_RESERVE|MEM_COMMIT只是一些有用的东西,所以您不必两次调用‘`VirtualAlloc()’API,但实际上它们仍然是两个非常不同的操作。

NOTE3:MEM_COMMIT标志将在页面大小边界上提交页面,而使用MEM_RESERVEMEM_RESERVE|MEM_COMMIT将在大于页面大小的边界上保留或保留reserve+commit页面,从今天起,在所有版本的Windows上通常都是64K。您可以通过调用GetSystemInfo()获得这个号码。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26029374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档