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. 附件
以下是实验代码