Windows虚拟内存的使用(一)

虚拟内存API:

  VirtualAlloc:虚拟内存的申请

  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中,在使用该区域时不需要耗时换页操作。




你可能感兴趣的:(windows核心编程)