实验六:系统内存使用统计
一、实验目的
1.了解windows内存管理机制,理解页式存储管理技术。
2.熟悉Windows内存管理基本数据结构。
3.掌握WIndows内存管理基本API的使用。
二、实验准备知识:相关数据结构及API函数介绍
1.相关系统数据结构说明:
系统结构MEMORYSTATUS中包含当前物理内存和虚拟内存和虚拟内存信息,使用函数GlobalMemoryStatus()可以将这些信息存储在结构MEMORYSTATUS中。
结构原型:
Typedef struct_MRMORYSTATUS{
DWORD dwLength; //MOMORYSTATUS结构大小
DWORD dwMemoryLoad; //内存利用率
DWORD dwTotalPhys; //物理内存大小
DWORD dwAvailPhys; //空闲物理内存大小
DWORD dwTotalPageFile; //页文件大小
DWORD dwAvailPageFile; //空闲页文件大小
DWORD dwTotalVirtual; //虚拟地址空间大小
DWORD dwAvailVirtual; //空闲虚拟地址空间大小
} MEMORYSTATUS, *LPMEMORYSTAYUS;
成员说明:
dwLength;MEMORYSTATUS数据结构的大小,单位为字节。
dwMemoryLoad:当前内存利用率,取值范围为0~100%,0表示内存没有被使用,100%表示内存全部被使用。
dwTotalPhys:物理内存的总字节数。
dwAvailPhys:可用物理内存的字节数。
dwTotalPageFile:页文件的总字节数。页文件是虚拟内存系统占用的磁盘空间。
dwAvailPageFile:页文件中的可用字节数。
dwTotalVirtual:用户模式下调用进程可以访问的虚拟地址空间总字节数。
dwAvailVirtual:用户模式下调用进程虚拟地址空间中未提交和未保留的内存总字节数,即可用虚拟地址空间大小。
2.相关API函数介绍
获取系统物理内存和虚拟内存使用信息
原型:
VID GlobalMemoryStatus(
LPMEMORYSTATUS lpBuffer //指向MEMORYSTATUS数据结构
);
参数说明:
lpBuffer: 指向MEMORYSTATUS数据结构的指针,函数GlobaiMemoryStatus()将内存的当前信息存储在该结构中。
返回值:该参数没有返回值。
保留或提交某一点虚拟地址空间
函数VirtualAlloc()可以在调用进程的虚拟地址空间中保留或提交若干页面。保留意味着这段虚拟地址地址不能被使用,当提交时,这段虚拟地址才真正被分配给进程。
原型:
VPVOID VirtuailAlloc(
LPVOID lpAddress, //待分配空间的起始位置
DWORD dwSize, //待分配空间的大小
DWORD flAllocationType, //分配类型
DWORD flaProtect //存取保护的类型
);
参数说明:
①lpAddress:待分配空间的其实位置。若该值为NULL,系统将为其分配一合适的起始地址,否则用户要指定一个准确的起始地址。
②dwSize:待分配空间的大小。如果参数lpAddress不为NULL,则待分配空间在lpAddress~ lpAddress+ dwSize范围内。
③flAllocationType:分配类型,可以为表3-1所列标志的任意组合。
表3-1
标志 | 描述 |
---|---|
MEM_COMMIT | 提交,即在内存或磁盘页文件中分配物理内存 |
MEM_RESERVE | 保留进程的虚拟地址空间,而不分配物理内存。表留的空间在没有被释放之前,不能被其他分配操作如Malloe()和LocalAlloc()使用。被保留的地址空间可随后使用VirtuaiAlloc()函数提交 |
④flProtect:指定存取保护的类型。若虚拟地址空间已经被提交,则在指定下面任何一个属性时要随同PAGE_GUARD(页保护)和PAGE_NOCACHE(页无缓存)这两个属性。存取保护位的类型如表3-2所示。
标志 | 描述 |
---|---|
PAGE_READONLY | 被提交的虚拟地址空间只读 |
PAGE_READWRITE | 被提交的虚拟地址空间可读/写 |
PAGE_EXECUTE | 被提交的虚拟地址空间可执行 |
PAGE_EXECUTE_READ | 被提交的虚拟地址空间可执行、可读 |
PAGE_EXECUTE_READWRITE | 被提交的虚拟地址空间可执行、可读/写 |
PAGE_GUARD | 保护 |
PAGE_NOACCESS | 不允许访问 |
PAGE_NOCACHE | 无缓存 |
返回值:
如果函数调用成功,则返回值为已分配虚拟地址空间的起始地址。如果函数调用失败, 则返回值为NULL。若要得到更多的错误信息,可调用GetLast6Error()函数。
(3)释放或注销某一段虚拟地址空间
函数VirtualFree()用于释放或注销某一段虚拟地址空间。
原型:
BOOL VirtualFree(
LPVOID lpAddress, //待分配空间的起始位置
DWORD dwSize, //待分配空间的大小
DWORD dwFreeType //释放操作类型
);
参数说明:
①lpAddress: 待释放空间的起始位置。如果dwFreeType值为MEM_RELEASE,该参数必须使用VirtualAlloc()函数返回的地址。
②dwSize: 待释放空间的大小。如果dwFreeType值为MEM_RELEASE,该参数必须为0,否则待释放空间在lpAddress~ lpAddress+dwSize范围内。
③dwFreeType: 释放类型。可以为表3-3所示标志的任意组合。
表3-3 释放类型
标志 | 描述 |
---|---|
MEM_DECOMMIT | 注销提交,如果注销一个没有提交的虚拟地址空间,也不会导致失败,即提交或没有提交的虚拟地址空间都可以注销 |
MEM_RELEASE | 释放保留的虚拟地址空间,如果使用该标志,dwSize参数必须为0,否则函数失败 |
返回值:
如果函数调用成功,则返回值为非零。
如果函数调用失败,则返回值为零。若要得到更多的错误信息,可调用GetLastError()函数。
(4)分配内存空间
原型:
void *malloc(site_t size);
参数说明:
Size:要分配内存大小,单位为B(字节)。
返回值:
该函数返回分配内存空间void类型的指针。如果返回NULL,说明没有有效的内存空间可供分配。
(5)释放内存空间
原型:
Void free(void * memblock);
参数说明:
*memblock:要释放的内存地址。
返回值:无。
三、实验内容
使用Windows系统提供的函数和数据结构显示系统存储空间的使用情况,当内存和虚拟存储空间变化时,观察系统显示变化情况。
// MALLOC.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MALLOC.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// The one and only application object
CWinApp theApp;
using namespace std;
void GetMemSta(void)
{
MEMORYSTATUS MemInfo ;
GlobalMemoryStatus (&MemInfo) ;
printf("\t Current Memory Status is : \n") ;
printf("\t Total Physical Memory is % dMB\n",MemInfo. dwTotalPhys/(1024*1024)) ;
printf("\t Available Physical Memoryis % 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) ;
}
int _tmain(int arcg, TCHAR* argv[],TCHAR* envp[])
{
int nRetCode = 0 ;
LPVOID BaseAdder ;
char * str ;
GetMemSta() ;
printf("Now Allocate 32M Virtual Memory and 2M Physical Memory\n\n") ;
BaseAdder = VirtualAlloc(NULL,1024*1024*32,MEM_RESERVE,
PAGE_READWRITE) ;
if (BaseAdder == 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(BaseAdder,0,MEM_RELEASE) == 0);
printf("Release Allocation Fail\n ");
free (str) ;
GetMemSta() ;
return nRetCode;
}
四、实验结果与总结
(1)程序开始运行时,显示可用物理内存为106MB,可用页文件大小为399MB,可用虚拟内存为2021MB。
(2)当分别使用函数VirtualAlloc()和malloc()分配了32MB虚拟内存和2MB物理内存后,系统显示可用物理内存为104MB,可用页文件大小为365MB,可用虚拟内存为1987MB。
(3)当分别使用函数VirtualFree()和free()释放了32MB虚拟内存和2MB物理内存后,系统的显示情况又恢复到了(1)的情况。