Windows提供3种进行内存管理的方法:
n 虚拟内存:管理大型对象或结构数组。
n 内存映射文件:管理大型数据流(通常来自文件)及多进程共享数据。
n 内存堆栈:管理大量的小对象。
管理虚拟内存的函数可以用来直接保留一个地址空间区域,提交物理存储器,设置保护属性。一、地址空间中保留及提交一个区域:
PVOID VirtualAlloc( // 如无足够大的区域保留或提交,返回NULL
PVOID pvAddress, // 一般 = NULL,但也可以选择特定的内存地址(必须在用户方式分区中)
SIZE_T dwSize, // 字节数,按分配粒度进行
DWORD fdwAllocationType, // 保留区域=MEM_RESERVE;提交物理存储器=MEM_CMMIT;从上至下 = MEM_TOP_DOWN;
DWORD fdwProtect); //保护属性:PAGE_READWRITE……
保留和提交可以分开进行。但何时提交有技巧。四种办法:
n 始终设法提交。如果已经提交,系统就不会提交更多的物理存储器。较慢!
n 使用VirtualQuery查询是否已经提交。更差!
n 保留一个已经提交和未提交的记录。难以跟踪!
n 结构化异常处理方法。参见C25。
二、回收虚拟内存和释放地址空间区域:
BOOL VirtualFree(
LPVOID pvAddress, // 释放、回收整个区域时=区域基地址;回收某些RAM=要回收的第一个页面的内存地址
SIZE_T dwSize, // 字节数,按分配粒度进行
DWORD fdwFreeType); // 回收=MEM_DECOMMIT;释放=MEM_RELEASE。
何时回收?
n 设计数据结构大小是页面大小的整数倍,当该结构不再使用,就可回收。
n 保留一个正在使用的结构的记录(位图),初值=0,使用时位置1,当不用时,检查在同一页面的相邻位,如果全=0,则回收。
n 实现一个无用单元收集函数,并在结构中添加bInUse(BOOL)单元。并有一个低优先级的函数,在空闲时遍历所有结构,回收不用的页面。
一、改变内存页面的保护属性:
BOOL VirtualProtect(
PVOID pvAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD fpOldProtect);
二、清除物理内存的内容:
调用VirtualAlloc,fdwAllocationType = MEM_RESET.
三、地址窗口扩展AWE(适用于Win2000):
a) 为窗口保留地址空间:
PVOID pvWin = VirtualAlloc(NULL, ulBytes, MEM_RESERVE|MEM_PHYSICAL, PAGE_READWRITE);
b) 分配RAM页面:
AllocateUserPhysicalPages(GetCurrentProcess(), &ulPages, RAMPages);
不能跨进程共享RAM块。
c) 把RAM页面与窗口关联:
MapUserPhysicalPages(pvWin, ulPages, RAMPages);
d) 使用窗口虚拟地址
e) 释放RAM页面:
FreeUserPhysicalPages(GetCurrentProcess(), &ulPages, RAMPages);
f) 销毁地址窗口:
VirtualFree(pvWin, 0, MEM_RELEASE);