Windows编程--虚拟内存基础

 系统信息

 许多操作系统的值是根据主机而定的,比如页面的大小分配粒度的大小等。这些值决不应该用硬编码的形式放入你的源代码。相反,你始终都应该在进程初始化的时候检索这些值,并在你的源代码中使用检索到的值。GetSystemInfo函数将用于检索与主机相关的值

 

VOID GetSystemInfo(LPSYSTEM_INFO psinf);


 

SYSTEM_INFO数据结构的样子。

typedef struct _SYSTEM_INFO

{

union

{

DWORD dwOemId;
//Obsolete, do not use

struct

{

WORD wProcessorArchitecture;

WORD wReserved;

};

};

DWORD dwPageSize;

LPVOID lpMinimumApplicationAddress;

LPVOID lpMaximumApplicationAddress;

DWORD_PTR dwActiveProcessorMask;

DWORD dwNumberOfProcessors;

DWORD dwProcessorType;

DWORD dwAllocationGranularity;

WORD wProcessorLevel;

WORD wProcessorRevision;

} SYSTEM_INFO,
*LPSYSTEM_INFO;

 

与内存有关的成员函数(其它变可参看MSDN

dwPageSize 用于显示CPU的页面大小。在x86 CPU上,这个值是4096字节。在Alpha CPU 上,这个值是8192字节。在IA-64上,这个值是8192字节

 lpMinimumApplicationAddress用于给出每个进程的可用地址空间的最小内存地址。在Windows 98上,这个值是4 194 304,或0x00400000,因为每个进程的地址空间中下面的4MB是不能使用的。在Windows 2000上,这个值是65 5360x00010000,因为每个进程的地址空间中开头的64KB总是空闲的

 lpMaximumApplicationAddress用于给出每个进程的可用地址空间的最大内存地址。在Windows 98 上,这个地址是2 147 483 6470x7FFFFFFF,因为共享内存映射文件区域和共享操作系统代码包含在上面的2GB分区中。在Windows 2000上,这个地址是内核方式内存开始的地址,它不足64KB

 dwAllocationGranularity 显示保留的地址空间区域的分配粒度

 

虚拟内存的状态

Windows函数GlobalMemoryStatus可用于检索关于当前内存状态的动态信息:

VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);

当调用GlobalMemoryStatus时,必须传递一个MEMORYSTATUS结构的地址。下面显示了MOMORYSTATUS的数据结构。

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结构的大小。

 

如果希望应用程序在内存大于4GB的计算机上运行,或者合计交换文件的大小大于4GB,那么可以使用新的GlobalMemoryStatusEx函数:

MEMORYSTATUSEX结构的地址:

BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst);

 

必须给该函数传递新的

typedef struct _MEMORYSTATUSEX

{

DWORD dwLength;

DWORD dwMemoryLoad;

DWORDLONG ullTotalPhys;

DWORDLONG ullAvailPhys;

DWORDLONG ullTotalPageFile;

DWORDLONG ullAvailPageFile;

DWORDLONG ullTotalVirtual;

DWORDLONG ullAvailVirtual;

DWORDLONG ullAvailExtendedVirtual;

} MEMORYSTATUSEX,
*LPMEMORYSTATUSEX;

 

这个结构与原先的MEMORYSTATUS结构基本相同,差别在于新结构的所有成员的大小都是6 4位宽,因此它的值可以大于4GB。最后一个成员是ullAv ailExtendedVirtual,用于指明在调用进程的虚拟地址空间的极大内存(VLM)部分中未保留内存的大小。该VLM部分只适用于某些配置中的某些CPU结构。 

 确定地址空间的状态

 Windows提供了一个函数,可以用来查询地址空间中内存地址的某些信息(如大小,存储器类型和保护属性等)。

这个函数称为VirtualQuery

DWORD VirtualQuery(

LPCVOID pvAddress,

PMEMORY_BASIC_INFORMATION pmbi,

DWORD dwLength);

 

Windows还提供了另一个函数,它使一个进程能够查询另一个进程的内存信息

DWORD VirtualQueryEx(

HANDLE hProcess,

LPCVOID pvAddress,

PMEMORY_BASIC_INFORMATION pmbi,

DWORD dwLength);

 

这两个函数基本相同,差别在于使用VirtualQueryEx时,可以传递你想要查询的地址空间信息的进程的句柄。调试程序和其他实用程序使用这个函数最多,几乎所有的应用程序都只需要调用VirtualQuery函数。

当调用VirtualQueryEx)函数时,

pvAddress参数必须包含你想要查询其信息的虚拟内存地址。

Pmbi参数是你必须分配的MEMORY_BASIC_INFORMATION结构的地址。该结构在WinNT.h文件中定义为下面的形式:

typedef struct _MEMORY_BASIC_INFORMATION

{

PVOID BaseAddress;

PVOID AllocationBase;

DWORD AllocationProtect;

SIZE_T RegionSize;

DWORD State;

DWORD Protect;

DWORD Type;

} MEMORY_BASIC_INFORMATION,
*PMEMORY_BASIC_INFORMATION;


最后一个参数是dwLength用于设定MEMORY_BASIC_INFORMATION结构的大小。VirtualQueryEx)函数返回拷贝到缓存中的字节的数量。

 

 FangSH  19:08 2011-1-6

   

原文地址:https://www.cnblogs.com/fangshenghui/p/1929070.html