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
[解决办法]
VirtualAlloc((LPVOID)(300*65536 + 8192), 1,
------------------------------------------------
我的理解是预订了 (8102+1)对齐到4096大小的区间,也就是3个页面。
接下来你调拨3个页面没问题,超过就不行了。
VirtualAlloc((LPVOID)(300*65536), 1,
--------------------------------------
这样才是预订了1个页面的大小。
应该和起始地址取整到64K后剩余的“余数”有关。