实验四:内存监视一、实验目的了解当前系统中内存的使用情况,包括系统地址空间的布局,物理内存的使用情况;能实时显示某个进程的虚拟地址空间布局和工作集信息等。二、实验内容设计一个内存监视器,能实时地显示当前系统中内存的使用情况,包括系统地址空间的布局,物理内存的使用情况;能实时显示某个进程的虚拟地址空间布局和工作集信息等。相关的系统调用:GetSystemInfo,VirtualQueryEx,VirtualAlloc,GetPerformanceInfo,GlobalMemoryStatusEx...三、实验环境硬件配置:联想IdeaPadY480笔记本。内存4G,硬盘1T。操作系统:Windows7四、程序设计与实现打印出内存的相关信息,调用的函数有GetSystemInfo,VirtualQueryEx,VirtualAlloc,GetPerformanceInfo,GlobalMemoryStatusExt等。五、实验代码、结果和分析实验代码://实验四.cpp:定义控制台应用程序的入口点。//#includestdafx.h//MemoryWatcher.cpp:定义控制台应用程序的入口点。//#includestdafx.h#includeiostream#includecstdio#includewindows.h#includetchar.h#includepsapi.h#includetlhelp32.h#includeshlwapi.h#includeiomanip#includeconio.h#pragmacomment(lib,psapi.lib)#pragmacomment(lib,Shlwapi.lib)#pragmawarning(disable:4996)usingnamespacestd;#defineWIDTH10#defineDIV(1024*1024)//WINAPI得到当前console的(x,y)voidconsole_gotoxy(intx,inty){//得到当前console的句柄HANDLEhc=GetStdHandle(STD_OUTPUT_HANDLE);COORDcursor={x,y};//设置新的cursor位置SetConsoleCursorPosition(hc,cursor);}//WINAPI设置当前console的(x,y)voidconsole_getxy(int&x,int&y){//得到当前console的句柄HANDLEhc=GetStdHandle(STD_OUTPUT_HANDLE);//屏幕缓冲区信息CONSOLE_SCREEN_BUFFER_INFOcsbi;//得到相应缓冲区信息GetConsoleScreenBufferInfo(hc,&csbi);x=csbi.dwCursorPosition.X;y=csbi.dwCursorPosition.Y;}HANDLEGetProcessHandle(intProcessID){returnOpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);}//显示保护标记,该标记表示允许应用程序对内存进行访问的类型inlineboolTestSet(DWORDdwTarget,DWORDdwMask){return((dwTarget&dwMask)==dwMask);}#defineSHOWMASK(dwTarget,type)\if(TestSet(dwTarget,PAGE_##type))\{cout,#type;}voidShowProtection(DWORDdwTarget){//定义的页面保护方式SHOWMASK(dwTarget,READONLY);SHOWMASK(dwTarget,GUARD);SHOWMASK(dwTarget,NOCACHE);SHOWMASK(dwTarget,READWRITE);SHOWMASK(dwTarget,WRITECOPY);SHOWMASK(dwTarget,EXECUTE);SHOWMASK(dwTarget,EXECUTE_READ);SHOWMASK(dwTarget,EXECUTE_READWRITE);SHOWMASK(dwTarget,EXECUTE_WRITECOPY);SHOWMASK(dwTarget,NOACCESS);}//遍历整个虚拟内存,显示单个进程虚拟地址空间布局voidWalkVM(HANDLEhProcess){SYSTEM_INFOsi;//系统信息结构ZeroMemory(&si,sizeof(si));//初始化GetSystemInfo(&si);//获得系统信息MEMORY_BASIC_INFORMATIONmbi;//进程虚拟内存空间的基本信息结构ZeroMemory(&mbi,sizeof(mbi));//分配缓冲区,用于保存信息LPCVOIDpBlock=(LPVOID)si.lpMinimumApplicationAddress;//循环整个应用程序地址空间while(pBlocksi.lpMaximumApplicationAddress){//获得下一个虚拟内存块的信息if(VirtualQueryEx(hProcess,//进程句柄pBlock,//开始位置&mbi,//缓冲区sizeof(mbi))==sizeof(mbi))//长度的确认,如果失败则返回0{//块的结尾指针LPCVOIDpEnd=(PBYTE)pBlock+mbi.RegionSize;TCHARszSize[MAX_PATH];StrFormatByteSize(mbi.RegionSize,szSize,MAX_PATH);//显示块地址和长度cout.fill('0');couthexsetw(8)(DWORD)pBlock--hexsetw(8)(DWORD)pEnd(wcslen(szSize)==7?(:()szSize);//显示块的状态switch(mbi.State){caseMEM_COMMIT:printf(Committed);break;caseMEM_FREE:printf(Free);break;caseMEM_RESERVE:printf(Reserved);break;}//显示保护if(mbi.Protect==0&&mbi.State!=MEM_FREE){mbi.Protect=PAGE_READONLY;}ShowProtection(mbi.Protect);//显示类型switch(mbi.Type){caseMEM_IMAGE:printf(,Image);break;caseMEM_MAPPED:printf(,Mapped);break;caseMEM_PRIVATE:printf(,Private);break;}//检测可执行的映像TCHARszFilename[MAX_PATH];if(GetModuleFileName((HMODULE)pBlock,//实际虚拟内存的模块句柄szFilename,//完全指定的文件名称MAX_PATH)0)//实际使用的缓冲区长度{//除去路径并显示PathStripPath(szFilename);printf(%s,szFilename);}printf(\n);//移动块指针以获得下一个块pBlock=pEnd;}}}//关于当前系统的信息voidShowProcessAddress(){intlineX=0,lineY=0;intflag=0;SYSTEM_INFOsys_info;//系统信息结构ZeroMemory(&sys_info,sizeof(sys_info));//初始化while(!kbhit()){//使用winapi控制缓冲区刷新输出if(flag==0){console_getxy(lineX,lineY);flag++;}else{console_gotoxy(lineX,lineY);}//获得系统信息GetSystemInfo(&sys_info);printf(虚拟内存分页大小:%dKB\n,sys_info.dwPageSize/1024);printf(处理器总数:%d\n,sys_info.dwNumberOfProcessors);printf(处理器架构:%d\n,sys_info.dwProcessorType);printf(虚拟内存粒度:%dKB\n,sys_info.dwAllocationGranularity/1024);printf(体系结构相关的处理器等级:%d\n,sys_info.wProcessorLevel);printf(体系结构相关的处理器修订:%x\n,sys_info.wProcessorRevision);printf(应用最小地址:0x%0.8x\n,sys_info.lpMinimumApplicationAddress);printf(应用最大地址:0x%0.8x\n,sys_info.lpMaximumApplicationAddress);printf(应用可用虚拟内存大小:%0.2fGB\n,((DWORD)sys_info.lpMaximumApplicationAddress-(DWORD)sys_info.lpMinimumApplicationAddress)/(1024.0*1024.0*1024.0));Sleep(1000);}}voidShowMemory(){intlineX=0,lineY=0;intflag=0;MEMORYSTATUStotal;total.dwLength=sizeof(total);while(!kbhit()){//使用winapi控制缓冲区刷新输出if(flag==0){console_getxy(lineX,lineY);flag++;}else{console_gotoxy(lineX,lineY);}//得到当前物理内存和虚拟内存GlobalMemoryStatus(&total);cout加载的内存:total.dwMemoryLoad%\n;cout总的物理内存:total.dwTotalPhys/DIVMB\n;cout可用物理内存:total.dwAvailPhys/DIVMB\n;cout总的虚拟内存:(total.dwTotalVirtual/DIV)MB\n;cout可用虚拟内存:(total.dwAvailVirtual/DIV)MB\n;cout总的页的大小:total.dwTotalPageFile/DIVMB\n;cout可用页大小:total.dwAvailPageFile/DIVMB\n;Sleep(1000);}}voidShowPerformance(){intlineX=0,lineY=0;intflag=0;PERFORMANCE_INFORMATIONperfor_info;perfor_info.cb=sizeof(perfor_info);while(!kbhit()){//使用winapi控制缓冲区刷新输出if(flag==0){console_getxy(lineX,lineY);flag++;}else{console_gotoxy(lineX,lineY);}GetPerformanceInfo(&perfor_info,sizeof(perfor_info));cout分页大小:perfor_info.PageSize/1024KBendl;cout系统提交的页面总数:perfor_