首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

VirtualAlloc终究一次最少预定多少进程地址空间

2013-09-06 
VirtualAlloc到底一次最少预定多少进程地址空间?本帖最后由 kelleniiii 于 2013-09-01 11:42:35 编辑int _

VirtualAlloc到底一次最少预定多少进程地址空间?
本帖最后由 kelleniiii 于 2013-09-01 11:42:35 编辑

int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

SYSTEM_INFO info = {0};
GetSystemInfo(&info);
cout<< "页面大小: " << info.dwPageSize <<endl;
cout<< "分配粒度: " << info.dwAllocationGranularity <<endl;
LPVOID p = VirtualAlloc((LPVOID)(300*65536 + 8192), 1, MEM_RESERVE, PAGE_READWRITE);
if (p)
{
cout<<"Reserve successed! " << p <<endl;
}
else
{
cout<<"Reserve failed! " << p  <<endl;
}
LPVOID p1 = VirtualAlloc((LPVOID)p, info.dwPageSize * 3, MEM_COMMIT, PAGE_READWRITE);
if (p1)
{
cout<<"Commit successed! " <<endl;
}
else
{
cout<<"Commit failed! " <<endl;
cout<<"Last Error: " <<GetLastError()<<endl;
}
getchar();
return 0;
}

以上代码运行结果是:
页面大小: 4096
分配粒度: 65536
Reserve successed! 012C0000
Commit successed!

如果将VirtualAlloc((LPVOID)p, info.dwPageSize * 3, MEM_COMMIT, PAGE_READWRITE);
中的info.dwPageSize * 3改为info.dwPageSize * 3 + 1 的话,结果是这样:
页面大小: 4096
分配粒度: 65536
Reserve successed! 012C0000
Commit failed!
Last Error: 487

如果说内存在调拨前必须先预定的话,说明VirtualAlloc预定的最小范围是12KB,也就是3个页面的大小,
为什么不是1个页面的大小?
据Windows核心编程一书上说:系统始终都根据CPU页面大小的整数倍来预定区域。
那么我如果要预定1个字节的话,最小单位也应该是4KB,一个页面才对啊。
求分析!
windows 内存 cpu
[解决办法]
引用:
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

SYSTEM_INFO info = {0};
GetSystemInfo(&info);
cout<< "页面大小: " << info.dwPageSize <<endl;


cout<< "分配粒度: " << info.dwAllocationGranularity <<endl;
LPVOID p = VirtualAlloc((LPVOID)(300*65536 + 8192), 1, MEM_RESERVE, PAGE_READWRITE);
if (p)
{
cout<<"Reserve successed! " << p <<endl;
}
else
{
cout<<"Reserve failed! " << p  <<endl;
}
LPVOID p1 = VirtualAlloc((LPVOID)p, info.dwPageSize * 3, MEM_COMMIT, PAGE_READWRITE);
if (p1)
{
cout<<"Commit successed! " <<endl;
}
else
{
cout<<"Commit failed! " <<endl;
cout<<"Last Error: " <<GetLastError()<<endl;
}
getchar();
return 0;
}


以上代码运行结果是:
页面大小: 4096
分配粒度: 65536
Reserve successed! 012C0000
Commit successed!

如果将VirtualAlloc((LPVOID)p, info.dwPageSize * 3, MEM_COMMIT, PAGE_READWRITE);
中的info.dwPageSize * 3改为info.dwPageSize * 3 + 1 的话,结果是这样:
页面大小: 4096
分配粒度: 65536
Reserve successed! 012C0000
Commit failed!
Last Error: 487

如果说内存在调拨前必须先预定的话,说明VirtualAlloc预定的最小范围是12KB,也就是3个页面的大小,
为什么不是1个页面的大小?
据Windows核心编程一书上说:系统始终都根据CPU页面大小的整数倍来预定区域。
那么我如果要预定1个字节的话,最小单位也应该是4KB,一个页面才对啊。
求分析!


 VirtualAlloc((LPVOID)(300*65536 + 8192), 1,
------------------------------------------------
我的理解是预订了 (8102+1)对齐到4096大小的区间,也就是3个页面。
接下来你调拨3个页面没问题,超过就不行了。

 VirtualAlloc((LPVOID)(300*65536), 1,
--------------------------------------
这样才是预订了1个页面的大小。
应该和起始地址取整到64K后剩余的“余数”有关。

热点排行