0%

Windows核心编程 - 应用程序中使用虚拟内存

最近在学习 Win32编程,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习Win32开发的童鞋们提供一份参考。

本系列博文均根据学习《Windows核心编程》一书总结而来;

运行环境:

  • 操作系统: Windows 10家庭版
  • 编译器:Visual Studio 2019

应用程序中使用虚拟内存

Windows提供了三种内存管理的方法,它们分别是:

  • 虚拟内存,适合用来管理大型对象或结构数组
  • 内存映射文件,适合用来管理大型数据流以及在单个计算机上运行的多个进程间共享数据
  • 内存对战,适合用来管理大量的小对象

地址空间中保留区域

通过调用VirtualAlloc函数,可以在进程的地址空间中保留一块区域;

1
2
3
4
LPVOID VirtualAlloc(LPVOID lpAddress, 			//保留在哪个区域,一般为NULL
DWORD dwSize, //保留区域大小,必须是页的整数倍
DWORD flAllocationType, //分配的类型
DWORD flProtect ); //保护属性

保留区域中提交存储器

当确定一个区域后,必须将物理存储器提交,然后才可以访问该区域中包含的内存地址。系统从它的页文件中将已提交的物理存储器分配给一个区域。

同时进行区域的保留和内存的提交

1
PVOID pvMem = VirtualAlloc(NULL,99*1024,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);

系统首先会区搜索地址空间,如果空间不足,则返回NULL;如果有足够的区域,系统就将物理存储器提交给整个区域;

回收虚拟空间

若要回收映射到一个区域的物理内存,或者释放这个地址空间区域,可调用VirtualFree函数:

1
2
3
BOOL VirtualFree(LPVOID lpAddress, //内存基地址
DWORD dwSize, //填0
DWORD dwFreeType ); //MEM_RELEASE 告诉系统所映射的内存区域已提交并释放

改变保护属性

Windows提供了可以改变已经提交的物理内存的一个或多个页面的保护属性;

1
2
3
4
BOOL VirtualProtect( LPVOID lpAddress, 	//内存基地址
DWORD dwSize, //保护的字节数
DWORD flNewProtect, //保护属性,要修改的保护属性
PDWORD lpflOldProtect ); //用原来的属性填充这个DWORD