【实验要求】
通过本实验,要求学生能够了解在Windows 2000/XP中如何控制存储空间。具体的要求如下:
(1)在程序中利用一个线程模拟各种虚存活动,比如虚存的保留、提交等。
(2)在程序中运行另一个监控线程来实时监视系统当前所进行的虚存操作,并将监测到的这些操作的信息从控制台输出;要求本线程和上一个虚存活动模拟线程保持同步,即模拟线程一旦有某一模拟活动则监控线程就应当随即监控到该活动的信息。
(3)在利用监控线程监视内存活动的同时汇报整个存储系统的使用情况。
【实验步骤】
(1) 打开VC ,选择菜单项File ->New ,选择projects 选项卡并建立一个名为VIRTUMEM 的win32 console applicatoin工程。创建时注意指定创建该工程的目录。
(2) 在工程中创建源文件VIRTUMEM.cpp :选择菜单项Project ->Add to project ->Files , 此时将打开个新窗口,在其中的“文件名”输入栏中输入自己想要创建的文件名,这里是VIRTUMEM . cpp 。接着询问是否创建新文件,回答yes 。然后,出现如图2 -4 所示窗口,通过Workspace->Fileview->Source Files打开该文件,在其中编辑源文件并保存。
图2 -4 创建并编辑源程序文件
(3) 设置编译环境,然后调用菜单项Buils->Rebuild all进行编辑连接,可以在指定的工程目录下得到debug ->VIRTUMEN.exe程序,现在即可在控制台以指定的参数运行VIRTUMEM . exe.
【实验分析】
程序运行时,模拟线程进行各种虚存操作,这些活动导致了程序虚存空间和系统存储资源的变化。监控线程给出了监控到的这些活动和变化的信息。程序给出了整个内存系统的各个全局统计量,包括物理内存使用量和页面文件使用情况等。通过这些统计量的变化可以分析当前的虚存活动对存储系统带来的变化。在分析的过程中可以帮助学生理解一些重要的内容,比如程序在进行一次虚存提交过后,显示的可用物理存储反而变多了,这是因为Windows 的内存管理发现某个进程在一段时间没有运行后,会将它的部分页面转移到页面文件中去。所以虽然本实验程序的进程目前分配了一些内存,但是总的可用物理内存数量还是增多了。作为验证,可以检查一下此时可用页面文件的数量是否减少。
【实验结果】
1)分析和总结程序实现的过程和功能
①main函数创建两个线程,来执行simulator和inspector。
②simulator先获取一个随机数的种子,然后在死循环中通过sleep来控制速度,通过随机数来进行虚存的各种操作:虚存的保留与提交、虚存的注销、虚存的注销并释放虚存空间、改变虚存内存页的保护、锁定虚拟内存页、虚存的保留,同时更改Actnum的值来进行连续的操作。如果Actnum是不为0的,会等待inspector捕捉上一个模拟动作。
③inspector通过全局变量Actnum的改变来监视simulator的模拟活动,根据Actnum的值来显示当前执行动作,并在最后将Actnum重置为0,来进行下一个模拟动作。
2)给出运行结果截图
3)根据程序的功能,对运行结果进行解释。
虚存的注销和释放虚存空间都失败了,所以没有被监控线程监控到。改变虚存内存页的保护操作时,可以看到分配时访问保护还是40,当前访问保护变成了20,说明保护更改成功。锁定虚存内存页是的目前状态还是0X1000,但是到了虚存的保留就变成了0X2000,代表了保留,并且可用的虚存空间减少了,说明一部分的虚存空间以及被保留。
【源程序】
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <time.h>
unsigned _stdcall simulator(void *);
unsigned _stdcall inspector(void *);
LPVOID BASE_PTR;
int Actnum=0;
//主函数,主要是用于启动用于模拟虚存活动和进行监控的两个线程
int main(int argc, char* argv[])
{
unsigned ThreadID[2];
_beginthreadex(NULL,0,simulator,NULL,0,&ThreadID[0]);
_beginthreadex(NULL,0,inspector,NULL,0,&ThreadID[1]);
getchar();
return 0;
}
//模拟一系列的虚存活动,作为一个独立的线程运行
unsigned _stdcall simulator(void *)
{
DWORD OldProtect;
int randnum;
printf("Now the simulator procedure has been started.\n");
//产生一个随机数种子
srand( (unsigned)time (NULL) );
/