实验六
一、实验目的
(1)了解Windows内存管理机制,理解页式存储管理技术。
(2)熟悉Windows内存管理基本数据结构。
(3)掌握Windows内存管理基本API的使用。
二、实验准备
相关系统数据结构说明
系统结构MEMORYSTATUS中包含当前物理内存和虚拟内存和虚拟内存信息,使用函数GlobaiMemoryStatus() 可以将这些信息存储在结构MEMORYSTATUS中。
结构原型:
Typedef struct_MRMORYSTATUS{
DWORD dwLength; //MOMORYSTATUS结构大小,单位字节
DWORD dwMemoryLoad; //内存利用率,范围0~100%
DWORD dwTotalPhys; //物理内存大小
DWORD dwAvailPhys; //空闲物理内存大小
DWORD dwTotalPageFile; //页文件大小
DWORD dwAvailPageFile; //空闲页文件大小
DWORD dwTotalVirtual; //虚拟地址空间大小
DWORD dwAvailVirtual; //空闲虚拟地址空间大小
} MEMORYSTATUS, *LPMEMORYSTAYUS;
返回值:
该参数没有返回值。
获取系统物理内存和虚拟内存使用信息: GlobaiMemoryStatus()
原型:
VID GlobalMemoryStatus(
LPMEMORYSTATUS lpBuffer //指向MEMORYSTATUS数据结构
);
返回值:
如果函数调用成功,则返回值为已分配虚拟地址空间的起始地址。如果函数调用失败, 则返回值为NULL。若要得到更多的错误信息,可调用GetLast6Error()函数。
保留或提交某一点虚拟地址空间: VirtualAlloc()
函数VirtualAlloc()可以在调用进程的虚拟地址空间中保留或提交若干页面。保留意味着这段虚拟地址地址不能被使用,当提交时,这段虚拟地址才真正被分配给进程。
原型:
VPVOID VirtuaiAlloc(
LPVOID lpAddress, //待分配空间的起始位置
DWORD dwSize, //待分配空间的大小
DWORD flAllocationType, //分配类型
DWORD flaProtect //存取保护的类型
);
返回值:
如果函数调用成功,则返回值为已分配虚拟地址空间的起始地址。如果函数调用失败,则返回值为NULL。若要得到更多的错误信息,可调用GetLast6Error()函数。
释放或注销某一段虚拟地址空间: VirtualFree()
原型:
BOOL VirtualFree(
LPVOID lpAddress, //待分配空间的起始位置
DWORD dwSize, //待分配空间的大小
DWORD dwFreeType //释放操作类型
);
返回值:
如果函数调用成功,则返回值为非零。
如果函数调用失败,则返回值为零。若要得到更多的错误信息,可调用GetLastError()函数。
分配内存空间
原型:
void *malloc(site_t size); // Size:要分配内存大小,单位为B(字节)
返回值:
该函数返回分配内存空间void类型的指针。如果返回NULL,说明没有有效的内存空间可供分配。
释放内存空间
原型:
void free(void * memblock); //*memblock:要释放的内存地址
返回值:无
三、实验内容
(一)实验内容
使用Windows系统提供的函数和数据结构显示系统存储空间的使用情况,当内存和虚拟存储空间变化时,观察系统显示变化情况。
(二)主要代码
// GetMemoryStatus.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "GetMemoryStatus.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void GetMemSta(void);
/
// The one and only application object
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
LPVOID BaseAddr;
char *str;
GetMemSta();
printf("Now Allocate 32M Virtual Memory and 2M Physical Memory\n\n");
BaseAddr=VirtualAlloc(NULL,1024*1024*32,MEM_COMMIT,PAGE_READWRITE);
if(BaseAddr == NULL)
printf("Virtual Allocate Fail\n");
str=(char*)malloc(1024*1024*2);
GetMemSta();
printf("Now Release 32M Virtual Memory and 2M Physical Memory\n\n");
if(VirtualFree(BaseAddr,0,MEM_RELEASE)==0)
printf("Release Allocation Fail\n");
free(str);
GetMemSta();
return nRetCode;
}
void GetMemSta(void)
{
MEMORYSTATUS MemInfo;
GlobalMemoryStatus(&MemInfo);
printf("Current Memory Status is:\n");
printf("\t Total Phycial Memory is %dMB\n",MemInfo.dwTotalPhys/(1024*1024));
printf("\t Available Physical Memory is %dMB\n",MemInfo.dwAvailPhys/(1024*1024));
printf("\t Total Page File is %dMB\n",MemInfo.dwTotalPageFile/(1024*1024));
printf("\t Available Page File is %dMB\n",MemInfo.dwAvailPageFile/(1024*1024));
printf("\t Total Virtual Memory is %dMB\n",MemInfo.dwTotalVirtual/(1024*1024));
printf("\t Available Virtual Memory is %dMB\n",MemInfo.dwAvailVirtual/(1024*1024));
printf("\t Memory Load is %d%%\n\n",MemInfo.dwMemoryLoad);
}
四、实验结果与总结
运行结果:
总结:
1.通过结果发现可用内存常常小于总共内存,这是因为当系统运行时就已经占用了部分内存,系统不同占用的内存也有差别,比如win7就比XP占内存大得多。
2.解决LINK : fatal error LNK1104: cannot open file "Debug/xx.exe"的问题:
在C:/Program Files/Microsoft Visual Studio/myprojiects下是找不到你写的工程文件的,因为在这个目录下写东西是需要管理员权限的,所以系统才会报“cannot open file”的错误,解决的办法是关闭软件,然后以管理员权限运行该软件,这样就可以完美运行调试程序了
3.VirtualProtect改变指定虚拟内存分页的保护属性,函数原型如下:
BOOL VirtualProtect(
LPVOID lpAddress, // 目标地址起始位置
DWORD dwSize, // 大小
DWORD flNewProtect, // 请求的保护方式
PDWORD lpflOldProtect // 保存老的保护方式
);
将页面锁定在物理内存中使用VirtualLock函数。这样页面将不会被交换到硬盘上,提高了访问的效率,如果要解除它,可以使用VirtualUnLock。
VirtualLock(
LPVOID lpAddress, //输入参数,虚拟内存基地址
SIZE_T dwSize //输入参数,内存大小
);
VirtualUnlock(
LPVOID lpAddress, //输入参数,虚拟内存基地址
SIZE_T dwSize //输入参数,内存大小
);