第1 4章 虚拟内存
这一章不再介绍抽象的概念,而要具体介绍几个Windows函数,这些函数能够提供关于系统内存管理以及进程中的虚拟地址空间等信息。
14.1 系统信息
许多操作系统的值是根据主机而定的,比如页面的大小,分配粒度的大小等。这些值决不应该用硬编码的形式放入你的源代码。相反,你始终都应该在进程初始化的时候检索这些值,并在你的源代码中使用检索到的值。
下面函数将用于检索与主机相关的值:
void GetSystemInfo(LPSYSTEM_INFO psinf)
必须传递SYSTEM_INFO结构的地址给这个函数。这个函数将初始化所有的结构成员然后返回。下面是SYSTEM_INFO数据结构的样子。
typedef struct _SYSTEM_INFO
{
union{
DWORD dwOemId;
struct {
WORD wProcessorArchitecture;
WORD wReserved;
};
};
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
DWORD wProcessorLevel;
DWORD wProcessorRevision;
}SYSTEM_INFO,*LPSYSTEM_INFO;
当系统引导时,它要确定这些成员的值是什么。对于任何既定的系统来说,这些值总是相同的,因此决不需要为任何既定的进程多次调用该函数。由于有了GetSystemInfo函数,因此应用程序能够在运行的时候查询这些值。
在该结构的所有成员中,只有4个成员与内存有关:
dwPageSize----用于显示CPU的页面大小。在x86 CPU上,这个值是4096字节。在Alpha CPU 上,这个值是8192字节。在IA-64上,这个值是8192字节。
lpMinimumApplicationAddress----用于给出每个进程的可用地址空间的最小内存地址。在Windows 98上,这个值是4 194 304,或0x00400000,因为每个进程的地址空间中下面的4MB是不能使用的。在Windows 2000上,这个值是65 536或0x00010000,因为每个进程的地址空间中开头的64KB总是空闲的。
lpMaximumApplicationAddress----用于给出每个进程的可用地址空间的最大内存地址。在Windows 98 上,这个地址是2 147 483 647或0x7FFFFFFF,因为共享内存映射文件区域和共享操作系统代码包含在上面的2GB分区中。在Windows 2000上,这个地址是内核方式内存开始的地址,它不足64KB。
dwAllocationGranularity----显示保留的地址空间区域的分配粒度。
14.2 虚拟内存的状态
Windows函数GlobalMemoryStatus可用于检索关于当前内存状态的动态信息:
void GlobalMemoryStatus(LPMEMORYSTATUS pmst);
当调用该函数时,必须传递一个MEMORYSTATUS结构的地址。下面显示了该数据结构:
typedef struct _MEMORYSTATUS
{
DWORD dwLength;
DWORD dwMemoryLoad;
SIZE_T dwTotalPhys;
SIZE_T dwAvailPhys;
SIZE_T dwTotalPageFile;
SIZE_T dwAvailPageFile;
SIZE_T dwTotalVirtual;
SIZE_T dwAvailVirtual;
}MEMORYSTATUS,*LPMEMORYSTATUS;
在调用GlobalMemoryStatus之前,必须将dwLength成员初始化为用字节表示的结构的大小,即一个MEMORYSTATUS结构的大小。这个初始化操作使得Microsoft能够将成员添加给将来的Windows版本中的这个结构,而不会破坏现有的应用程序。当调用GlobalMemoryStatus时,它将对该结构的其余成员进行初始化并返回。
14.3 确定地址空间的状态
Windows提供了一个函数,可以用来查询地址空间中内存地址的某些信息(如大小,存储器类型和保护属性等)
DWORD VirtualQuery(
LPCVOID pvAddress,
PMEMORY_BASIC_INFORMATION pmbi,
DWORD dwLength
)
pvAddress参数必须包含你想要查询其信息的虚拟内存地址。
Pmbi参数是你必须分配的MEMORY_BASIC_INFORMATION结构的地址。该结构在Wi n N T. h文件中定义。
dwLength参数用于设定MEMORY_BASIC_INFORMATION结构的大小。