Windows虚拟内存的使用(一)

虚拟内存API:
VirtualAlloc:虚拟内存的申请
【Windows虚拟内存的使用(一)】VirtualFree:虚拟内存的释放
代码如下:

/************************************************************************/ /* 功能:以直接预定并提交方式进行虚拟内存申请和赋值 参数:无 返回:无 */ /************************************************************************/ VOID Func() { //1 预定并提交内存 VOID *pRecv = VirtualAlloc(NULL,//系统决定区域的位置 1024,//申请的内存区域 MEM_RESERVE | MEM_COMMIT,//预定并提交的方式 PAGE_READWRITE); //内存页的保护方式(只能对整个内存页设置,不能对一个页的部分内存设置) float* pfArray = (float*)pRecv; //循环赋值 for (int i = 0; i < 1024/sizeof(float); i++) { pfArray[i] = 1.0f * rand(); } //直接释放 VirtualFree(pRecv,0,MEM_RELEASE); }






VirtualAlloc用来申请虚拟内存空间,第一个参数表示分配区域的开始地址,如果指定地址的内存区域是预定的,那么指定地址向上取整到最近的分配粒度边界。如果指定地址已经被预定和提交,那么指定地址向下取整到最近的分配粒度边界;第二个参数是申请虚拟内存空间的大小(单位是字节),例如上面就申请了1kB的虚拟内存空间;第三个参数是申请内存的方式,如果你只是以MEM_RESERVE进行内存的申请,系统没有为你这次的申请实际分配物理内存,你也就不能对该区域进行内存读写了。如果你想往物理内存中进行数据的读写,你必须以MEM_COMMIT进行内存的申请;第四个参数是内存页的保护方式。内存页有PAGE_NOACCESS,PAGE_READONLY等等保护方式,你可以查看一下MSDN。
注意:用VirtualAlloc以MEM_RESERVE方式申请内存,申请的大小小于64kB或者不是64kB的倍数时,系统会为你预定64kB或者是64kB倍数的虚拟内存空间。如果再想申请已被预订区域时,申请操作会失败。用VirtualAlloc以MEM_COMMIT方式申请一块小于一个页的大小(4kB)或着不是4kB倍数的内存时,系统会在先前预定空间分配一块4kB或者是4kB倍数大小的内存,并且该内存区域全都被清零,这样就没有必要对该区域进行清零操作。(如果只预定1个BYTE,系统至少也会为你预定64KB的空间,如果只提交1BYTE,系统至少也会提交4KB的一个页面)
预定和提交分开方式分开操作代码如下:

/************************************************************************/ /* 功能:提交和保留分开方式进行内存的操作 参数:无 返回:无 */ /************************************************************************/ VOID Func2() { //1预定1M的空间 BYTE* pMem = (BYTE*)VirtualAlloc(NULL,1024 * 5,MEM_RESERVE,PAGE_READWRITE); //提交页面 VirtualAlloc(pMem+1024,3*1024,MEM_COMMIT,PAGE_READWRITE); //操作已提交的页面 double* pdbArray = (double*)(pMem+1024); for (int i=0; i<(3*1024)/sizeof(double); i++) { pdbArray[i] = 1.0f * rand(); } //释放物理页面 VirtualFree(pMem+1024,3*1024,MEM_DECOMMIT); //释放空间 VirtualFree(pMem,0,MEM_RELEASE); }



备注:
1 通过释放和再提交页面可以快速的将页面清零。
2 VirtualAlloc的flAllocationType可以指定下列扩展的标志位(需要指定MEM_RESERVE或MEM_COMMIT):
MEM_LARGE_PAGES:启用大页面支持(大于等于2M每个页面,原前的4K页面相对被称为小页面)
MEM_TOP_DOWN:从高端地址保留空间(默认是从低端向高端搜索)
MEM_WRITE_WATCH:开启页面写入监视,利用GetWriteWatch可以得到写入页面的统计情况,利用ResetWriteWatch可以重置起始计数。
MEM_PHYSICAL:用于PAE支持。
3 flAllocationType可以指定MEM_RESET标志(单独使用不能和其他组合使用),告诉系统指定的区域的内容没有改变,不需要将该区域的内容写到页面文件中。以便使这块区域长期存放在RAM中,在使用该区域时不需要耗时换页操作。




?? ??

    推荐阅读