概述
作者:shenzi
链接:http://blog.csdn.net/shenzi
操作系统中有许多值是由系统所运行的主机决定的,如页面大小和分配粒度等。我们应该在进程初始化时取得这些值,然后在代码中使用它们。GetSystemInfo函数用来取得与主机相关的值:
VOID GetSystemInfo(LPSYSTEM_INFO psi);
我们需要传一个SYSTEM_INFO结构的地址给这个函数。该函数会对数据结构中的所有成员进行初始化,然后返回。下面是SYSTEM_INFO结构的地定义:
typedef struct _SYSTEM_INFO {
union {
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;
成员
|
描述
|
---|---|
dwPageSize | 表示CPU页面的大小。 |
lpMinimumApplicationAddress | 给出每个进程可用地址空间中最小的内存地址。由于每个进程的地址空间中最开始的64KB始终闲置的,因此该值为65536,或0x00001000 |
lpMaximumApplicationAddress | 给出每个进程的私有地址空间中最大的可用内存地址 |
dwAllocationGranularity | 表示用于预定地址空间区域的分配粒度。 |
成员
|
描述
|
---|---|
wReserved | 为今后扩展而保留,请勿使用 |
dwNumberOfProcessors | 表示机器中的CPU数量。双核机器上该值为:2 |
dwActiveProcessorMask | 一个位掩码,用来表示哪些CPU处于活动状态(可以用来运行线程) |
dwProcessorType | 已经作废,请勿使用 |
wProcessorArchitecture | 表示处理器的体系结构,如x 86, x 64, or IA-64. |
wProcessorLevel | 进一步细分处理器的体系结构,比如 Intel 奔腾 III or IV. 如果需要确定CPU支持哪些特性,我们应该调用IsProcessorFeaturePresent 函数,而不是使用这个字段 |
wProcessorRevision | 进一步对 wProcessorLevel 进行细分 |
VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);
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函数:
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;
3.确定地址空间的状态
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);
MEMORY_BASIC_INFORMATION结构:
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;
成 员
|
描 述
|
---|---|
BaseAddress | 它的值等于将参数 pvAddress 向下取整到页面的大小 |
AllocationBase | 标识出区域的基地址,该区域包含参数pvAddress 所指定的地址 |
AllocationProtect | 标识出在最开始预订区域时为该区域指定的保护属性 |
RegionSize | 标识出区域的大小,以字节为单位。区域的起始地址为BaseAddress , 区域中的所有页面拥有相同的保护属性、状态以及类型 |
State | 标识出区域页面的状态 (MEM_FREE , MEM_RESERVE , 或MEM_COMMIT ) 如果状态为 MEM_FREE ,那么 pvAddress AllocationBase , AllocationProtect , Protect , 及 Type 成员都没有意义。如果状态为MEM_RESERVE , 那么 Protect 成员没有意义 |
Protect | 针对所有相邻的页面(前提是其保护属性、状态和类型与其中包含 pvAddress 参数中所指定地址的页面相同 ),标识出它们的保护属性 (PAGE_* ) for all adjoining pages that have the same protection attributes, state, and type as the page containing the address specified in the pvAddress parameter. |
Type | 标识出区域页面的类型 (MEM_IMAGE , MEM_MAPPED , 或MEM_PRIVATE ) |
最后
以上就是欣慰灯泡为你收集整理的Windows核心编程:探索虚拟内存作者:shenzi 链接:http://blog.csdn.net/shenzi 的全部内容,希望文章能够帮你解决Windows核心编程:探索虚拟内存作者:shenzi 链接:http://blog.csdn.net/shenzi 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复