实验四内存监视.docx
- 文档编号:15889727
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:16
- 大小:63.68KB
实验四内存监视.docx
《实验四内存监视.docx》由会员分享,可在线阅读,更多相关《实验四内存监视.docx(16页珍藏版)》请在冰点文库上搜索。
实验四内存监视
实验四:
内存监视
一、实验目的
了解当前系统中内存的使用情况,包括系统地址空间的布局,物理内存的使用情况;能实时显示某个进程的虚拟地址空间布局和工作集信息等。
二、实验内容
设计一个内存监视器,能实时地显示当前系统中内存的使用情况,包括系统地址空间的布局,物理内存的使用情况;能实时显示某个进程的虚拟地址空间布局和工作集信息等。
相关的系统调用:
GetSystemInfo,VirtualQueryEx,VirtualAlloc,GetPerformanceInfo,GlobalMemoryStatusEx...
三、实验环境
硬件配置:
联想IdeaPadY480笔记本。
内存4G,硬盘1T。
操作系统:
Windows7
四、程序设计与实现
打印出内存的相关信息,调用的函数有GetSystemInfo,VirtualQueryEx,VirtualAlloc,GetPerformanceInfo,GlobalMemoryStatusExt等。
五、实验代码、结果和分析
实验代码:
//实验四.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
//MemoryWatcher.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include"conio.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(pBlock { //获得下一个虚拟内存块的信息 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'); cout< <<"--" < <<(wcslen(szSize)==7? "(": "(")< <<")"; //显示块的状态 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<<"加载的内存: "< cout<<"总的物理内存: "< cout<<"可用物理内存: "< cout<<"总的虚拟内存: "<<(total.dwTotalVirtual/DIV)<<"MB\n"; cout<<"可用虚拟内存: "<<(total.dwAvailVirtual/DIV)<<"MB\n"; cout<<"总的页的大小: "< cout<<"可用页大小: "< 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<<"分页大小: "< cout<<"系统提交的页面总数: "< cout<<"系统提交的页面限制: "< cout<<"系统提交的页面峰值: "< cout<<"按页分配的物理内存总数: "< cout<<"按页分配的物理内存可用量: "< cout<<"系统物理内存占用: "<<(perfor_info.PhysicalTotal-perfor_info.PhysicalAvailable)*(perfor_info.PageSize/1024)*1.0/DIV<<"GB"< cout<<"系统物理内存可用: "< cout<<"系统物理内存总数: "< cout<<"系统缓存总量: "< cout<<"系统内核内存占据页面总数: "< cout<<"系统内核内存占据分页页面数: "< cout<<"系统内核内存占据不分页页面数: "< cout<<"系统句柄总量: "< cout<<"系统进程总量: "< cout<<"系统线程总量: "< Sleep(1000); } } //如果pid为-1,获取所有进程 voidShowAllProcess(intpid) { PROCESSENTRY32pe32;//存储进程信息 pe32.dwSize=sizeof(pe32);//在使用这个结构前,先设置它的大小 PROCESS_MEMORY_COUNTERSppsmemCounter;//struct,存储进程内存的使用信息,便于用函数GetProcessMemoryInfo获取进程的相关信息 ppsmemCounter.cb=sizeof(ppsmemCounter);//初始化大小 HANDLEhProcessSnap; hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//快照句柄 HANDLEhProcess;//进程句柄 if(hProcessSnap==INVALID_HANDLE_VALUE){ printf("创建进程快照失败.\n"); exit(0); } //遍历进程快照,轮流显示每个进程的信息 BOOLbMore=Process32First(hProcessSnap,&pe32);//获取系统快照第一个进程的信息,结果返回到pe32结构里 printf("进程的工作集信息: \n"); while(bMore){ if(pid! =-1) { if(pid==pe32.th32ProcessID) { wcout<<"进程名称: "< cout<<"进程ID: "< cout<<"线程数: "< hProcess=GetProcessHandle(pe32.th32ProcessID); GetProcessMemoryInfo(hProcess,&ppsmemCounter,sizeof(ppsmemCounter));//进程内存使用信息(存储于ppsmemCounter中) cout<<"已提交: "< cout<<"工作集: "< cout<<"工作集峰值: "< } bMore=Process32Next(hProcessSnap,&pe32);//获取系统快照下一个进程信息 } else { wcout<<"进程名称: "< cout<<"进程ID: "< cout<<"线程数: "< hProcess=GetProcessHandle(pe32.th32ProcessID); GetProcessMemoryInfo(hProcess,&ppsmemCounter,sizeof(ppsmemCounter));//进程内存使用信息(存储于ppsmemCounter中) cout<<"已提交: "< cout<<"工作集: "< cout<<"工作集峰值: "< bMore=Process32Next(hProcessSnap,&pe32);//获取系统快照下一个进程信息 } } CloseHandle(hProcessSnap);//关闭快照 } voidQuerySingleProcess() { intlineX=0,lineY=0; intflag=0; HANDLEhProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//快照句柄 HANDLEhProcess;//进程句柄 if(hProcessSnap==INVALID_HANDLE_VALUE){ printf("CreateToolhelp32Snapshot调用失败.\n"); exit(0); } cout<<"输入进程ID,查询进程的内存分布空间: "< intPID=0; cin>>PID; hProcess=GetProcessHandle(PID); ShowAllProcess(PID); WalkVM(hProcess)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 内存 监视