实验六 系统内存使用统计

实验六 系统内存使用统计

一、实验目的

  1. 了解Windows内存管理机制,理解页式存储管理技术。
  2. 熟悉Windows内存管理基本数据结构。
  3. 掌握Windows内存管理基本API的使用。

二、实验准备

相关数据结构及API函数介绍

  1. 相关系统数据结构说明

系统结构MEMORYSTATUS中包含当前物理内存和虚拟内存和虚拟内存信息,使用函数GlobaiMemoryStatus()可以将这些信息存储在结构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:用户模式下调用进程虚拟地址空间中未提交和未保留的内存总字节数,即可用虚拟地址空间大小。
  1. 相关API函数介绍

获取系统物理内存和虚拟内存使用信息

原型:

VID GlobalMemoryStatus(
	LPMEMORYSTATUS lpBuffer             //指向MEMORYSTATUS数据结构
);

参数说明:

  • lpBuffer: 指向MEMORYSTATUS数据结构的指针,函数GlobaiMemoryStatus()将内存的当前信息存储在该结构中。

返回值:
该参数没有返回值。

保留或提交某一点虚拟地址空间

函数VirtualAlloc()可以在调用进程的虚拟地址空间中保留或提交若干页面。保留意味着这段虚拟地址地址不能被使用,当提交时,这段虚拟地址才真正被分配给进程。

原型:

VPVOID VirtuaiAlloc( 
	LPVOID lpAddress,                   //待分配空间的起始位置
	DWORD dwSize,                       //待分配空间的大小
	DWORD flAllocationType,             //分配类型
	DWORD flaProtect                    //存取保护的类型
);

参数说明:

  • lpAddress:待分配空间的其实位置。若该值为NULL,系统将为其分配一合适的起始地址,否则用户要指定一个准确的起始地址。

  • dwSize:待分配空间的大小。如果参数lpAddress不为NULL,则待分配空间在lpAddress~ lpAddress+ dwSize范围内。

  • flAllocationType:分配类型,可以为表3-1所列标志的任意组合。

  • 表3-1

    标志描述
    MEM_COMMMIT提交,即在内存或磁盘页文件中分配物理内存
    MEM_RESERVE保留进程的虚拟地址空间,而不分配物理内存。表留的空间在没有被释放之前,不能被其他分配操作如Malloe()和LocalAlloc()使用。被保留的地址空间可随后使用VirtuaiAlloc()函数提交
  • flProtect:指定存取保护的类型。若虚拟地址空间已经被提交,则在指定下面任何一个属性时要随同PAGE_GUARD(页保护)和PAGE_NOCACHE(页无缓存)这两个属性。存取保护位的类型如表3-2所示。

  • 表3-2

    描述
    AGE_READONLY被提交的虚拟地址空间只读
    AGE_READWRITE被提交的虚拟地址空间可读/写
    AGE_EXECUTE被提交的虚拟地址空间可执行
    AGE_EXECUTE_READ被提交的虚拟地址空间可执行、可读
    AGE_EXECUTE_READWRITE被提交的虚拟地址空间可执行、可读/写
    AGE_GUARD保护
    AGE_NOACCESS不允许访问
    AGE_NOCACHE无缓存

返回值:
如果函数调用成功,则返回值为已分配虚拟地址空间的起始地址。如果函数调用失败,则返回值为NULL。若要得到更多的错误信息,可调用GetLast6Error()函数。

释放或注销某一段虚拟地址空间

函数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

    描述
    EM_DECOMMIT注销提交,如果注销一个没有提交的虚拟地址空间,也不会导致失败,即提交或没有提交的虚拟地址空间都可以注销
    EM_RELEASE释放保留的虚拟地址空间,如果使用该标志,dwSize参数必须为0,否则函数失败

返回值:
如果函数调用成功,则返回值为非零。
如果函数调用失败,则返回值为零。若要得到更多的错误信息,可调用GetLastError()函数。

分配内存空间

原型:

   void *malloc(site_t size);

参数说明:

  • Size:要分配内存大小,单位为B(字节).

返回值:
该函数返回分配内存空间void类型的指针。如果返回NULL,说明没有有效的内存空间可供分配。

释放内存空间

原型:

Void free(void * memblock);

参数说明:

  • *memblock:要释放的内存地址。

返回值:无。

用法举例:

/*MALLOC.C:This grogram allocates memory with
*malloc,then frees the memory with free
*/
#include<stdlib.h>
   #include<stdio.h>
            #include<malloc.h>
            Void main(void)
           {
              Char * string;
              /*Allocate space for a path name*/
              String=malloc(_MAX_PATH);       //分配内存空间
              if(string==NULL)
                   printf(“Insufficient memory available\n”);
                   free(string);
                   printf(“Memory freed\n”);
              }
}

三、实验内容

(一)实验内容

使用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("\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) ;
}

四、实验结果和总结

  • 程序开始运行时,显示可用物理内存为1736MB,可用页文件大小为3774MB,可用虚拟内存为2031MB
  • 当分别使用函数VirtualAlloc()和malloc()分配了32MB虚拟内存和2MB物理内存后,系统显示可用物理内存为1734MB,可用页文件大小为3740MB,可用虚拟内存为1997MB
  • 当分别使用函数VirtualFree()和free()释放了32MB虚拟内存和2MB物理内存后,系统的显示情况又恢复到了开始的情况。
    image
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值