Windows核心编程系列文章仅作为实验报告和Windows编程学习参考,不作为任何技术文章,还望大佬们勿喷。

1. 实验名称

Windows内存、虚拟内存

2. 实验环境

  1. VS2015
  2. Windows 10

3. 实验目的

  1. 掌握windows内存体系结构,理解进程虚拟地址,虚拟地址空间分区,地址空间中区域,给区域调拨物理存储器的概念和基本过程
  2. 学会使用VirtualAlloc,VirtualFree,以及VirtualQuery虚拟内存相关函数使用
  3. 学会使用系统信息函数GetSystemInfo,以及GetComputerNameEx等相关函数使用

4. 实验内容、步骤及结果

1. 实验内容

  1. 采用虚拟内存函数VirtualAlloc,以及虚拟内存相关函数使用,分配一个64kb地址预订和物理调拨,并将字符串“20150111”(各自学号)赋值到虚拟内存;采用VirtualQuery进行查询虚拟内存情况,并然后调用VirtualFree释放虚拟内存。
  2. 设计一个内存监视器,能实时地显示当前系统中内存的使用情况,包括系统地址空间的布局,物理内存的使用情况;能实时显示某个进程的虚拟地址空间布局和工作集信息等。

2. 实验步骤

  1. 虚拟内存
  1. // experience3.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <string.h>
  5. #include <Windows.h>
  6. int _tmain(int argc, _TCHAR* argv[]) {
  7. char szText[] = "2015122075"; //分配一个64kb地址预订和物理调拨
  8. char* pszData = (char*)VirtualAlloc(NULL, 64 * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  9. if (pszData == NULL)
  10. {
  11. printf("分配失败.\n");
  12. }
  13. else
  14. {
  15. strcpy(pszData, szText); //将字符串“20151222075”(各自学号)赋值到虚拟内存
  16. printf("已将学号2015122075赋值到虚拟内存.\n");
  17. }
  18. MEMORY_BASIC_INFORMATION mbi; //查询虚拟内存分配
  19. VirtualQuery(pszData, &mbi, sizeof(mbi));
  20. printf("使用VirtualQuery获得的信息:\n"
  21. "BaseAddress:0x%.8x\nAllocationBase:0x%.8x\n"
  22. "AllocationProtect:0x%.8x\nRegionSize:%u\n"
  23. "State:0x%.8x\nProtect:0x%.8x\nType:0x%.8x\n",
  24. mbi.BaseAddress, mbi.AllocationBase,
  25. mbi.AllocationProtect, mbi.RegionSize,
  26. mbi.State, mbi.Protect, mbi.Type
  27. ); //释放虚拟内存
  28. VirtualFree(pszData, 0, MEM_RELEASE);
  29. system("pause");
  30. return 0;
  31. }
  1. 设计一个内存监视器
  1. // experience3-1.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. #include <Lmcons.h>
  6. void ShowSystemInfo(); //获取并显示硬件相关信息
  7. void GlobalMemoryStatusx(); //获取并显示内存信息
  8. void GetNames(); //获取并显示计算机名、用户名等信息
  9. int _tmain(int argc, _TCHAR* argv[])
  10. {
  11. ShowSystemInfo();
  12. GlobalMemoryStatusx();
  13. GetNames();
  14. getchar();
  15. return 0;
  16. }
  17. void ShowSystemInfo() //获取并显示硬件相关信息
  18. {
  19. SYSTEM_INFO si;
  20. GetSystemInfo(&si);
  21. printf("cpu页面大小:0x%.8X\n", si.dwPageSize);
  22. printf("进程的可用地址空间的最小内存地址:0x%.8X\n进程的可用地址空间的最大内存地址;0x%.8X\n", si.lpMinimumApplicationAddress, si.lpMaximumApplicationAddress);
  23. printf("\n处理器架构:");
  24. switch (si.wProcessorArchitecture)
  25. {
  26. case PROCESSOR_ARCHITECTURE_INTEL:
  27. printf("intel");
  28. printf(" CPU vendor is %d", si.wProcessorLevel);
  29. break;
  30. case PROCESSOR_ARCHITECTURE_IA64:
  31. printf("64 bits intel");
  32. break;
  33. case PROCESSOR_ARCHITECTURE_AMD64:
  34. printf("64 bits AMD");
  35. break;
  36. case PROCESSOR_ARCHITECTURE_UNKNOWN:
  37. printf("UNKNOWN");
  38. break;
  39. }
  40. printf("\n");
  41. }
  42. void GetNames() //获取计算机名、用户名等信息
  43. {
  44. DWORD dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
  45. DWORD dwUserNameLen = UNLEN + 1;
  46. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  47. TCHAR szUserName[UNLEN + 1];
  48. if (!SetComputerName("My_Computer"))
  49. {
  50. printf("Set Error %d", GetLastError());
  51. }
  52. GetComputerName(szComputerName, &dwComputerNameLen);
  53. printf("计算机名:%s\n", szComputerName);
  54. dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
  55. GetComputerNameEx(ComputerNameDnsHostname, szComputerName, &dwComputerNameLen);
  56. printf("ComputerNameDnsHostname: %s\n", szComputerName);
  57. dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
  58. GetComputerNameEx(ComputerNamePhysicalNetBIOS, szComputerName, &dwComputerNameLen);
  59. printf("ComputerNamePhysicalNetBIOS: %s\n", szComputerName);
  60. GetUserName(szUserName, &dwUserNameLen);
  61. printf("用户名:%s\n", szUserName);
  62. }
  63. void GlobalMemoryStatusx()
  64. {
  65. MEMORYSTATUS status; //定义存放内存信息的变量
  66. GlobalMemoryStatus(&status); //调用GlobalMemoryStatus函数获取内存信息
  67. //对得到的内存信息处理现实处理
  68. printf("总内存%d KB\n", status.dwTotalPhys / 1000); //现实内存大小
  69. printf("可使用物理内存%d KB\n", status.dwAvailPhys / 1000);
  70. printf("交换文件总大小%d KB\n", status.dwTotalPageFile / 1000);
  71. printf("使用的交换文件大小%d KB\n", status.dwAvailPageFile / 1000);
  72. printf("总虚拟内存%d KB\n", status.dwTotalVirtual / 1000);
  73. }

3. 实验结果(实验运行截图)

  1. 将学号赋值到虚拟内存中

【实验三】Windows内存、虚拟内存 - 图1

  1. 创建一个内存监视器

【实验三】Windows内存、虚拟内存 - 图2

5. 实验中的问题及心得

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

6. 附件

以下是实验代码

链接:https://pan.baidu.com/s/1RX4BTxtR0nflvDQ0gVhxbg
提取码:you0