1. 获取系统相关信息:
VOID GetSystemInfo( LPSTYSTEM_INFO psi);
其中SYSTEM_INFO结构体定义如下:
typedef struct _SYSTEM_INFO {
union {
DWORD dwOemId; //
struct {
WORD wProcessorArchitecture; //表示处理器的体系结构
WORD wReserved; //保留值.切勿使用
};
};
DWORD dwPageSize; //页的大小
LPVOID lpMinimumApplicationAddress; //给出每个进程可用地址空间中最小的内存地址.由于 //每个进程地址空间中最开始的64K是闲置的.因此该值为0x00001000
LPVOID lpMaximumApplicationAddress; //进程的私有地址空间最大可用内存地址
DWORD_PTR dwActiveProcessorMask;//位掩码,用来表示哪些CPU处于活动状态
DWORD dwNumberOfProcessors; //表示机器中CPU的数量
DWORD dwProcessorType; //已经作废
DWORD dwAllocationGranularity; //表示用于预定地址空间分配的分配粒度.
WORD wProcessorLevel; //细分处理器的结构(如奔腾,..)
WORD wProcessorRevision; //进一步细分处理器(相对于wProcessorLevel).
} SYSTEM_INFO;
如果想要得到处理器详细信息,我们可调用GetLogicalProcessorInformation来获取.
Microsoft提供了一个成为Windows 32-bit On Windows64 bit的模拟层(简称WOW64),当32位应用程序通过WOW64运行时,GetSystemInfo返回值和64 bit可能不同.确定其运行环境可调用以下函数:
BOOL IsWow64Process(//替代函数IsOs(OS_WOW6432):TRUE表示32位在64位上运行
HANDLE hProcess, //进程句柄
PBOOL pbWow64Process) //返回值,TRUE表示是
函数返回值:FALSE表示把某些无效的值用作参数.如果32应用程序在32位windows上运行(或者64位在64位上运行)也是返回FLASE.只有32位应用程序在WOW64上运行屏蔽WowProcess才返回TRUE.此时可以利用GetNativeSystemInfo来取得原来的SYSTEM_INFO结构: void GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo);
2. 虚拟内存状态:
VOID GlobalMemoryStatus( LPMEMORYSTSTUS lpBuffer)//使用前需初始化结构的大小
//即调用GlobalMemoryStatus
其中,MEMORYSTATUS结构如下:
ypedef struct _MEMORYSTATUS {
DWORD dwLength; //长度
DOWORD dwMemoryLoad;//大致告知系统有多忙
SIZE_T dwTotalPhys,//所有可用物理内存的总数
SIZE_T dwAvailPhys;//所有节点可用内存的总数
SIZE_T dwTotalPageFile;//表示硬盘上的也交换文件最多能存放多少子节点数据
SIZE_T dwAvailVirtual;//表示页文件中有多少字节尚未使用
SIZE_T dwTotalVirtual;//表示地址空间中为各进程私有的那部分的字节数
SIZE_T dwAvailVirtual;//表示有多少闲置的虚拟空间可供使用
}MEMORYSTATUS,*LPMEMORYSTATUS;
另外如果确定应用程序会装有4GB内存的机器上运行,或者页交换文件的大小可能会大于4GB,那么就应该调用新的GlobalMemoryStatusEx( LPMEMORYSTATUS pmst);
ypedef struct _MEMORYSTATUSEX{
DWORD dwLength;
DWORD dwMemoryLoad;
DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys;
DWORDLONG ullTotalPageFile;
DOWRDLONG ullAvaailPageFile;
DOWRDLONG ullTotalVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailExtendVirtual;//表示当前进程的虚拟地址空间中尚未 //被预定的那一大块内存地址空间的大小.该成员只对特定配置中特定类 //型的CPU体系结构才有意义
}MEMORYSTATUSEX,*LPMEMORYSTATUSEX;
3. 非统一内存访问(NUMA):是指多个CPU情况下,CPU技能访问本地内存节点,也能访问非本地内存节点.如果想要知道某个特定的NUMA节点的内存数量可以调用如下函数:
BOOL GetNumaAvailableMemoryNode(
UCHAR uNode,//用来表示节点
PULONGLONG pulAvailableBytes);//返回节点的内存数量
CPU驻留哪个节点查询函数:
BOOL GetNumaProcessorNode(
UCHAR Processor,
PUCHAR NodeNumber);
获取节点数:
BOOL GetNumaHighestNodeNumber(
PULONG pulHighestNodeNumber);
驻留在某个节点中的CPU列表:
BOOL GetNumaNodeProcessorMask(
UCHAR uNode, //节点的数字标示
[_out] PULONGLONG pulProcessorMask);//位掩码
获取进程当前工作集的大小和最大的工作集的大小:
BOOL GetProcessMemoryInfo(
HANDLE hProcess.//具备PROCESS_QUERY_INFORMATION和PROCESS_VM_READ //访问权限的句柄
PPROCESS_MEMORY_COUNTERS ppmc,//
DWORD cbSize); //结构的大小
typedef struct _PROCESS_MEMORY_COUNTERS {
DWORD cb;
DWORD PageFaultCount;
SIZE_T PeakWorkingSetSize;//曾经使用过内存数量的最大值
SIZE_T WorkingSetSize; //工作集大小
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivateUsage;//通过调用new,malloc或VirtualAlloc显示分配的内存数
} PROCESS_MEMORY_COUNTERS;
4. 虚拟内存映射表查询函数://查询本身进程
DWORD VirtualQuery(
LPCVOID pvAddress,//指向PMEMORY_BASIC_INFORMATION结构中填入相邻页面 //区间有关的信息
PMEMORY_BASIC_INFORMATION pmbi,
DWORD dwLength);
//查询非本身进程
DWORD VirtualQueryEx(
HANDLE hProcess,//待查询的进程句柄
LPCVOID pvAddress,
PMEMORY_BASIC_INFORMATION pmbi,
DWORD dwLength);//指向上一参数的结构大小
两个函数的返回值是实际使用字节数.
其中MEMORY_BASIC_INFORMATION结构定义如下:
tyopedef _MEMORY_BASIC_INFORMATION
{
PVOID BaseAddresss, //等于将参数pvAddress向下取整到页面的大小
PVOID AllocationBase; //标示出区域的基地址,该区域包含参数pvAddress所指定的地址
DWORD AllocationProtect; //标示出在最开始预订区域时为该区域指定的保护属性
SIZE_T RegionSize; //标示出区域的大小,以字节为单位.区域的起始地址为BaseAddress,
//区域中的所有页面拥有相同的保护属性,状态以及类型
DWORD State;//针对所有相邻的页面状态(MEM_FREE,MEM_RESERVE或MEM_COMMIT).如 //果状态为MEM_FREE.
//那么AllocationBase,AllocationProtect,Protect及Type成员都没有意义
DWORD Protect; //针对所有相邻的页面(前提是其保护属性,状态和类型与
//其中包含pvAddress参数中所指定地址的页面相同),标示出他们的保护属性(PAGE_*)
DWORD Type; //标示出区域中页面的类型(MEM_IMAGE,MEM_MAPPED或MEM_PRIVATE)
}MEMORY_BASIC_INFORMATION,PMEMORY_BASIC_INFORMATION;
为了得到更加详细的信息,可以使用作者封装的一个函数:
BOOL VMQuery(
HANDLE hProcess,
LPCVOID pvAddress,
PVMQUERY pVMQ);
PVMQ的定义:
typedef struct {
// Region information
PVOID pvRgnBaseAddress;//区域起始地址
DWORD dwRgnProtection; // PAGE_*相当于AllocationBase字段
SIZE_T RgnSize; //相当于RegionSize字段
DWORD dwRgnStorage; // MEM_*: Free, Image, Mapped, Private相当于State
DWORD dwRgnBlocks; //块的数量
DWORD dwRgnGuardBlks; // If > 0, region contains thread stack
BOOL bRgnIsAStack; // TRUE if region contains thread stack(通过猜测得到)
// Block information
PVOID pvBlkBaseAddress;//块的起始地址
DWORD dwBlkProtection; // PAGE_* 块的保护属性
SIZE_T BlkSize; //块的大小,以字节为单位
DWORD dwBlkStorage;// MEM_*: Free, Reserve, Image, Mapped, Private(表示块存储器的类型
} VMQUERY, *PVMQUERY;
注意:因为该函数运行起来需要调用多次VirtualQueryEx,这就意味着它的执行速度会很慢.