Windows核心编程系列文章仅作为实验报告和Windows编程学习参考,不作为任何技术文章,还望大佬们勿喷。
1. 实验名称
Windows内存、虚拟内存
2. 实验环境
- VS2015
- Windows 10
3. 实验目的
- 掌握windows内存体系结构,理解进程虚拟地址,虚拟地址空间分区,地址空间中区域,给区域调拨物理存储器的概念和基本过程
- 学会使用VirtualAlloc,VirtualFree,以及VirtualQuery虚拟内存相关函数使用
- 学会使用系统信息函数GetSystemInfo,以及GetComputerNameEx等相关函数使用
4. 实验内容、步骤及结果
1. 实验内容
- 采用虚拟内存函数VirtualAlloc,以及虚拟内存相关函数使用,分配一个64kb地址预订和物理调拨,并将字符串“20150111”(各自学号)赋值到虚拟内存;采用VirtualQuery进行查询虚拟内存情况,并然后调用VirtualFree释放虚拟内存。
- 设计一个内存监视器,能实时地显示当前系统中内存的使用情况,包括系统地址空间的布局,物理内存的使用情况;能实时显示某个进程的虚拟地址空间布局和工作集信息等。
2. 实验步骤
- 虚拟内存
// experience3.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <string.h>#include <Windows.h>int _tmain(int argc, _TCHAR* argv[]) {char szText[] = "2015122075"; //分配一个64kb地址预订和物理调拨char* pszData = (char*)VirtualAlloc(NULL, 64 * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);if (pszData == NULL){printf("分配失败.\n");}else{strcpy(pszData, szText); //将字符串“20151222075”(各自学号)赋值到虚拟内存printf("已将学号2015122075赋值到虚拟内存.\n");}MEMORY_BASIC_INFORMATION mbi; //查询虚拟内存分配VirtualQuery(pszData, &mbi, sizeof(mbi));printf("使用VirtualQuery获得的信息:\n""BaseAddress:0x%.8x\nAllocationBase:0x%.8x\n""AllocationProtect:0x%.8x\nRegionSize:%u\n""State:0x%.8x\nProtect:0x%.8x\nType:0x%.8x\n",mbi.BaseAddress, mbi.AllocationBase,mbi.AllocationProtect, mbi.RegionSize,mbi.State, mbi.Protect, mbi.Type); //释放虚拟内存VirtualFree(pszData, 0, MEM_RELEASE);system("pause");return 0;}
- 设计一个内存监视器
// experience3-1.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>#include <Lmcons.h>void ShowSystemInfo(); //获取并显示硬件相关信息void GlobalMemoryStatusx(); //获取并显示内存信息void GetNames(); //获取并显示计算机名、用户名等信息int _tmain(int argc, _TCHAR* argv[]){ShowSystemInfo();GlobalMemoryStatusx();GetNames();getchar();return 0;}void ShowSystemInfo() //获取并显示硬件相关信息{SYSTEM_INFO si;GetSystemInfo(&si);printf("cpu页面大小:0x%.8X\n", si.dwPageSize);printf("进程的可用地址空间的最小内存地址:0x%.8X\n进程的可用地址空间的最大内存地址;0x%.8X\n", si.lpMinimumApplicationAddress, si.lpMaximumApplicationAddress);printf("\n处理器架构:");switch (si.wProcessorArchitecture){case PROCESSOR_ARCHITECTURE_INTEL:printf("intel");printf(" CPU vendor is %d", si.wProcessorLevel);break;case PROCESSOR_ARCHITECTURE_IA64:printf("64 bits intel");break;case PROCESSOR_ARCHITECTURE_AMD64:printf("64 bits AMD");break;case PROCESSOR_ARCHITECTURE_UNKNOWN:printf("UNKNOWN");break;}printf("\n");}void GetNames() //获取计算机名、用户名等信息{DWORD dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;DWORD dwUserNameLen = UNLEN + 1;TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];TCHAR szUserName[UNLEN + 1];if (!SetComputerName("My_Computer")){printf("Set Error %d", GetLastError());}GetComputerName(szComputerName, &dwComputerNameLen);printf("计算机名:%s\n", szComputerName);dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;GetComputerNameEx(ComputerNameDnsHostname, szComputerName, &dwComputerNameLen);printf("ComputerNameDnsHostname: %s\n", szComputerName);dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;GetComputerNameEx(ComputerNamePhysicalNetBIOS, szComputerName, &dwComputerNameLen);printf("ComputerNamePhysicalNetBIOS: %s\n", szComputerName);GetUserName(szUserName, &dwUserNameLen);printf("用户名:%s\n", szUserName);}void GlobalMemoryStatusx(){MEMORYSTATUS status; //定义存放内存信息的变量GlobalMemoryStatus(&status); //调用GlobalMemoryStatus函数获取内存信息//对得到的内存信息处理现实处理printf("总内存%d KB\n", status.dwTotalPhys / 1000); //现实内存大小printf("可使用物理内存%d KB\n", status.dwAvailPhys / 1000);printf("交换文件总大小%d KB\n", status.dwTotalPageFile / 1000);printf("使用的交换文件大小%d KB\n", status.dwAvailPageFile / 1000);printf("总虚拟内存%d KB\n", status.dwTotalVirtual / 1000);}
3. 实验结果(实验运行截图)
- 将学号赋值到虚拟内存中

- 创建一个内存监视器

5. 实验中的问题及心得
- 掌握了关于内存和虚拟内存的相关函数,以及获取计算机信息的内容的一些函数。
- 实验中有一些函数例如GetComputerNameEx(),在vc不能够使用,百度后发现只能够在vs2005及以上版本才能使用,所以最好只能下载vs2015才编译代码。
- 在编写代码中遇到一些参数的类型不正确,后面后面将项目属性的字符集改为多字节字符集即可运行。
- 在查询完虚拟内存后需要将虚拟内存释放掉,不然会出错。
6. 附件
以下是实验代码
