虚拟内存——Windows核心编程学习手札之十四
虚拟内存
——Windows核心编程学习手札之十四
系统信息
有些操作系统的值是根据主机而定的,如页面大小、分配粒度大小等,这些值不用硬编码形式,进程初始化时应检索这些值以使用。函数GetSystemInfo函数用于检索与主机相关的值:
VOID GetSystemInfo(LPSYSTEM_INFO psinf);
传递SYSTEM_INFO结构的地址,该函数将初始化结构成员并返回。
typedef struct _SYSTEM_INFO{
union{
DWORD dwOemId;//obsolete,do not use
Struct{
WORD wProcessorArchitecture;//用于指明处理结构,如Intel、Alpha、 Intel64位lpha64位,主要在windows2000中;
WORD wReserved;
};
};
DWORD dwPageSize;//用于显示CPU页面大小,如x86是4096字节;Alpha是8192字节;IA-64是8192字节;
LPVOID lpMinimumApplicationAddress;//用于给出每个进程的可用地址空间的最小内存地址,如Windows98中是4 194 304或0x00400000,因为每个进程的地址空间中下面4MB是不能使用的,用户方式的分区在该地址之上;如windows2000中,这个值是65 536或0x000100000,因为每个进程的地址空间中开头的64KB是空闲的;
LPVOID lpMaximumApplicationAddress;//用户给出每个进程的可用地址空间的最大内存地址,如windows98,这个地址是2 147 483 647或0x7FFFFFFF,因为共享内存映射文件和共享操作系统代码包含在上面的2GB分区中;如windows2000,这个地址是内核方式内存开始的地址,不足64KB;
DWORD_PTR dwActiveProcessorMask;//一个位屏蔽,用于指明哪个CPU是活动的;
DWORD dwNumberOfProcessors;//用于指明计算机中的CPU数目;
DWORD dwProcessorType;//用于指明处理器类型,如Intel386、486/Pentium,主要在windows98中;
DWORD dwAllocationGranularity;//显示保留的地址空间区域的分配粒度,目前,所有windows平台都是65 356;
WORD wProcessorLevel;//用于进一步细分处理器的结构,如设定Intel Pentium Pro或Pentium Ⅱ,主要用于windows2000;
WORD wProcessorRevision;//用于进一步细分处理器的级别,用于windows2000;
}SYSTEM_INFO,*LPSYSTEM_INFO;
对既定的系统,这些值都是相同的,不需要在既定的进程中多次调用函数,通过GetSystemInfo函数应该程序可以查询关于系统中的这些值。
示例代码:
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
void ShowCPUInfo(WORD wProcessorArchitecture,WORD wProcessorLevel,WORD wProcessorRevision)
{
TCHAR strInfo[256];
memset(strInfo,0,256);
/*PROCESSOR_ARCHITECTURE_INTEL
PROCESSOR_ARCHITECTURE_MIPS
PROCESSOR_ARCHITECTURE_UNKNOWN
PROCESSOR_ARCHITECTURE_SHX
PROCESSOR_ARCHITECTURE_ARM */
switch(wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
if(wProcessorLevel==4)
{
wsprintf(strInfo,_T("处理器类型: Intel 80486"));
}
else if(wProcessorLevel==5)
{
wsprintf(strInfo,_T("处理器类型: Pentium"));
}
else
{
wsprintf(strInfo,_T("处理器类型: PROCESSOR_ARCHITECTURE_INTEL"));
}
break;
case PROCESSOR_ARCHITECTURE_MIPS:
switch(wProcessorLevel)
{
case 3:
wsprintf(strInfo,_T("处理器类型: MIPS R3000"));
break;
case 4:
wsprintf(strInfo,_T("处理器类型: MIPS R4000"));
break;
case 5:
wsprintf(strInfo,_T("处理器类型: MIPS R5000"));
break;
default:
wsprintf(strInfo,_T("处理器类型: PROCESSOR_ARCHITECTURE_MIPS"));
break;
}
break;
case PROCESSOR_ARCHITECTURE_SHX:
wsprintf(strInfo,_T("处理器类型: PROCESSOR_ARCHITECTURE_SHX"));
break;
case PROCESSOR_ARCHITECTURE_ARM:
if(wProcessorLevel==4)
{
wsprintf(strInfo,_T("处理器类型: ARM version 4"));
}
else
{
wsprintf(strInfo,_T("处理器类型: PROCESSOR_ARCHITECTURE_ARM"));
}
break;
default:
wsprintf(strInfo,_T("处理器类型: PROCESSOR_ARCHITECTURE_UNKNOWN"));
break;
}
}
int main(int argc, char* argv[])
{
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
ShowCPUInfo(sinf.wProcessorArchitecture,sinf.wProcessorLevel,sinf.wProcessorRevision);
TCHAR szBuf[256];
wsprintf(szBuf,_T("页面文件大小: %d 或 0x%08x"),sinf.dwPageSize,sinf.dwPageSize);
wsprintf(szBuf,_T("进程的最小内存地址: %d 或 0x%08x"),sinf.lpMinimumApplicationAddress,sinf.lpMinimumApplicationAddress);
wsprintf(szBuf,_T("进程的最大内存地址: %d 或 0x%08x"),sinf.lpMaximumApplicationAddress,sinf.lpMaximumApplicationAddress);
wsprintf(szBuf,_T("当前活动的CPU: %d"),sinf.dwActiveProcessorMask);
return 0;
}
虚拟内存的状态
Windows函数GlobalMemoryStatus可用于检索关于当前内存状态的动态信息:
VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);
当调用GlobalMemoryStatus时,要传递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结构的大小。
如应用程序在内存大于4GB的计算机上运行,或者合计交换文件的大小大于4GB,可用新的GlobalMemoryStatusEx函数:
BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst);
函数传递新的结构MEMORYSTATUSEX:
typedef struct _MEMORYSTATUSEX{
DWORD dwLength;
DWORD dwMemoryLoad;
DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys;
DWORDLONG ullTotalPageFile;
DWORDLONG ullAvailPageFile;
DWORDLONG ullTotalVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailExtendedVirtual;
}MEMORYSTATUSEX,*LPMEMORYSTATUSEX;
新结构和原来的MEMORYSTATUS基本相同,差别在于新结构的所有成员的大小都是64位宽,因此它的值可以大于4GB,最后一个成员ullAvailExtendedVirtual,用于指明在调用进程的虚拟地址空间的极大内存(VLM)部分中未保留内存的大小。该VLM部分只适用于某些配置中的某些CPU结构。
Windows提供了一个函数,可以用来查询地址空间中内存地址的某些信息(如大小,存储器类型和保护属性等)。函数VirtualQuery:
DWORD VirtualQuery(
LPCVOID pvAddress,
PMEMORY_BASIC_INFORMATION pmbi,
DWORD dwLength);
Windows也提供了VirualQueryEx函数,用于使一个进程能够查询另一个进程的内存信息:
DWORD VirtualQueryEx(
HANDLE hProcess,
LPCVOID pvAddress,
PMEMORY_BASIC_INFORMATION pmbi,
DWORD dwLength);
结构体MEMORY_BASIC_INFORMATION在WinNT.h中定义:
typedef struct _MEMORY_BASIC_INFORMATION{
PVOID BaseAddress;
PVOID AllocationBase;
PVOID AllocationProtect;
SIZE_T RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION,* PMEMORY_BASIC_INFORMATION;
函数VirtualQuery的最后一个参数是dwLength,用于设定MEMORY_BASIC_INFORMATION结构的大小。VirtualQuery(Ex)函数返回拷贝到缓存中的字节的数量。根据pvAddress参数中传递的地址,VirtualQuery(Ex)函数将关于共享相同状态、保护属性和类型的相邻页面的范围信息填入MEMORY_BASIC_INFORMATION结构中。
虚拟内存——Windows核心编程学习手札之十四相关推荐
- 在应用程序中使用虚拟内存——Windows核心编程学习手札之十五
在应用程序中使用虚拟内存 --Windows核心编程学习手札之十五 Windows提供了3种进行内存管理的方法: 1) 虚拟内存,最适合用来管理大量对象或结构数组: 2) 内存映射文件,最适合用来 ...
- DLL基础——Windows核心编程学习手札之十九
DLL基础 --Windows核心编程学习手札之十九 Windows API中的所有函数都包含在DLL中,3个最重要的DLL是Kernel32.dll,它包含用于管理内存.进程和线程的各个函数:Use ...
- 堆栈——Windows核心编程学习手札之十八
堆栈 --Windows核心编程学习手札之十八 堆栈可以用来分配许多较小的数据块,可以不考虑分配粒度和页面边界之类的问题,但分配和释放内存块的速度比其他机制要慢,并且无法直接控制物理存储器的提交和回收 ...
- 线程的堆栈——Windows核心编程学习手札之十六
线程的堆栈 --Windows核心编程学习手札之十六 系统会在进程的地址空间内保存一些区域,同时也会在进程地址空间内为线程的堆栈保留区域.线程都有自己的堆栈,创建时,系统就保留一个堆栈空间区域,并将相 ...
- 未处理异常和C++异常——Windows核心编程学习手札之二十五
未处理异常和C++异常 --Windows核心编程学习手札之二十五 当一个异常过滤器返回EXCEPTION_CONTINUE_SEARCH标识符时是告诉系统继续上溯调用树,寻找另外的异常过滤器,但当每 ...
- 插入DLL和挂接API——Windows核心编程学习手札之二十二
插入DLL和挂接API --Windows核心编程学习手札之二十二 如下情况,可能要打破进程的界限,访问另一个进程的地址空间: 1)为另一个进程创建的窗口建立子类时: 2)需要调试帮助时,如需要确定另 ...
- DLL的高级操作技术——Windows核心编程学习手札之二十
DLL的高级操作技术 --Windows核心编程学习手札之二十 显示加载DLL模块: HINSTANCE LoadLibrary(PCTSTR pszDLLPathName); HINSTANCE L ...
- 窗口消息——Windows核心编程学习手札之二十六
窗口消息 --Windows核心编程学习手札之二十六 Windows允许一个进程至多建立10000个不同类型的用户对象(user object):图符.光标.窗口类.菜单.加速键表等,当一个线程调用一 ...
- 异常处理程序和软件异常——Windows核心编程学习手札之二十四
异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...
最新文章
- 关于 synchronizeOnSession
- npc寻路问题 c++_《原神》游戏中最懒的NPC出现了,她要玩家找一朵甜甜花
- 814:The Letter Carrier's Rounds
- MVC扩展控制器工厂,通过继承DefaultControllerFactory来决定使用哪个接口实现,使用Ninject...
- boost::gregorian模块实现打印假期的测试程序
- SDNU 1330.Max Sum(最大子序列和)
- javafx之TableView的TaleCell
- Atmospheric Scattering
- SpringMVC 拦截器实现
- 图片热点的使用,html area 的用法
- Xcode 代码格式化/自动排版
- 银河水滴打响步态识别商用第一枪!3大产品1.35亿订单,工业视觉平台免费开放...
- Stage3D 入门资源汇总
- sqoop各类命令示范
- 安卓帧数监测软件_安卓查看帧数的软件
- 通过一个简单例子看懂遗传算法,附MATLAB代码
- 实力验证:金蝶EAS 8.2授权注册 (包含Apusic 9999连接数破解)
- kali-扫描主机-Nmap
- java this逃逸_java 中的 this 逃逸
- 【python爬虫】求人不如求己,自己动手写一个CSDN博客备份小工具?