实验虚拟存储器.docx
- 文档编号:8426396
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:12
- 大小:21.12KB
实验虚拟存储器.docx
《实验虚拟存储器.docx》由会员分享,可在线阅读,更多相关《实验虚拟存储器.docx(12页珍藏版)》请在冰豆网上搜索。
实验虚拟存储器
实验9、Windows虚拟内存
1背景知识
在Windows环境下,4GB的虚拟地址空间被划分成两个部分:
低端2GB提供给进程使用,高端2GB提供给系统使用。
这意味着用户的应用程序代码,包括DLL以及进程使用的各种数据等,都装在用户进程地址空间内(低端2GB)。
用户过程的虚拟地址空间也被分成三部分:
1)虚拟内存的已调配区(committed):
具有备用的物理内存,根据该区域设定的访问权限,用户可以进行写、读或在其中执行程序等操作。
2)虚拟内存的保留区(reserved):
没有备用的物理内存,但有一定的访问权限o
3)虚拟内存的自由区(free):
不限定其用途,有相应的PAGE_NOACCESS权限。
与虚拟内存区相关的访问权限告知系统进程可在内存中进行何种类型的操作。
例如,用户不能在只有PAGE_READONLY权限的区域上进行写操作或执行程序;也不能在只有PAGE_EXECUTE权限的区域里进行读、写操作。
而具有PAGE_NOACCESS权限的特殊区域,则意味着不允许进程对其地址进行任何操作。
在进程装入之前,整个虚拟内存的地址空间都被设置为只有PAGE_NOACCESS权限的自由区域。
当系统装入进程代码和数据后,才将内存地址的空间标记为已调配区或保留区,并将诸如EXECUTE、READWRITE和READONLY的权限与这些区域相关联。
如表1所示,给出了MEMORY_BASIC_INFORMATION的结构,此数据描述了进程虚拟内存空间中一组虚拟内存页面的当前状态,其中State项表明这些区域是否为自由区、已调配区或保留区;Protect项则包含了Windows系统为这些区域添加了何种访问保护;Type项则表明这些区域是可执行图像、内存映射文件还是简单的私有内存。
VirtualQueryEX()API能让用户在指定的进程中,对虚拟内存地址的大小和属性进行检测。
Windows还提供了一整套能使用户精确控制应用程序的虚拟地址空间的虚拟内存API。
一些用于虚拟内存操作及检测的API如表2所示。
表1MEMORY_BASIC_INFORMATION结构的成员
成员名称
目的
PVOIDBaseAddress
虚拟内存区域开始处的指针
PVOIDAllocationBase
如果这个特定的区域为子分配区的话,则为虚拟内存外面区域的指针;否则,此值与BaseAddress相同
DWORDAllocationProtect
虚拟内存最初分配区域的保护属性。
其可能值包括:
PAGE_NOACCESS,PAGE_READONLY,PAGE_READWRITE和PAGE_EXECUTE_READ
DWORDRegionSize
虚拟内存区域的字节数
DWORDState
区域的当前分配状态。
其可能值为MEM_COMMIT,MEM_FREE和MEM_RESERVE
DW()RDProtect
虚拟内存当前区域的保护属性。
可能值与AllocationProtect成员的相同
DWORDType
虚拟内存区域中出现的页面类型。
可能值为MEM_IMAGE,MEM_MAPPED和MEM_PRIVATE
表2虚拟内存的API
APl名称
描述
VirtualQueryEx()
通过填充MEMORY_BASIC_INFORMATION结构检测进程内虚拟内存的区域
VirtuaAlloc()
保留或调配进程的部分虚拟内存,设置分配和保护标志
VirtualFree()
释放或收回应用程序使用的部分虚拟地址
VirtualProtect()
改变虚拟内存区域保护规范
VirtualLock()
防止系统将虚拟内存区域通过系统交换到页面文件中
VirtualUnlock()
释放虚拟内存的锁定区域,必要时,允许系统将其交换到页面文件中
提供虚拟内存分配功能的是VinualAlloc()API。
该API支持用户向系统要求新的虚拟内存或改变已分配内存的当前状态。
用户若想通过VirtualAlloc()函数使用虚拟内存,可以采用两种方式通知系统:
1)简单地将内存内容保存在地址空间内。
2)请求系统返回带有物理存储区(RAM的空间或换页文件)的部分地址空间。
用户可以用flAllocationType参数(commit和reserve)来定义这些方式,用户可以通知Windows按只读、读写、不可读写、执行或特殊方式来处理新的虚拟内存。
与VirtualAlloc()函数对应的是VirtualFree()函数,其作用是释放虚拟内存中的已调配页或保留页。
用户可利用dwFreeType参数将已调配页修改成保留页属性。
VirtualProtect()是VirtualAlloc()的一个辅助函数,利用它可以改变虚拟内存区的保护规范。
2实验目的
1)通过实验了解Windows内存的使用,学习如何在应用程序中管理内存,体会Windows应用程序内存的简单性和自我防护能力。
2)学习检查虚拟内存空间或对其进行操作。
3)了解Windows的内存结构和虚拟内存的管理,进而了解进程堆和Windows为使用内存而提供的一些扩展功能。
3实验内容与步骤
虚拟内存的检测
清单2所示的程序使用VirtualQueryEX()函数来检查虚拟内存空间。
步骤1:
在“开始”菜单中单击“程序”、“MicrosoftVisualStudio6.0”、
“MicrosoftVisualC++6.0”,进入VisualC++窗口。
步骤2:
运行以下程序清单
清单2检测进程的虚拟地址空间
#include
#include
#include
#include
#pragmacomment(lib,"shlwapi.lib")
//以可读方式对用户显示保护的辅助方法。
//保护标记表示允许应用程序对内存进行访问的类型以及操作系统强制访问的类型
inlineboolTestSet(DWORDdwTarget,DWORDdwMask)
{
return((dwTarget&dwMask)==dwMask);
}
#defineSHOWMASK(dwTarget,type)\
if(TestSet(dwTarget,PAGE_##type))\
{std:
:
cout<<","<<#type;}
voidShowProtection(DWORDdwTarget)
{
SHOWMASK(dwTarget,READONLY);
SHOWMASK(dwTarget,GUARD);
SHOWMASK(dwTarget,NOCACHE);
SHOWMASK(dwTarget,READWRITE);
SHOWMASK(dwTarget,WRITECOPY);
SHOWMASK(dwTarget,EXECUTE);
SHOWMASK(dwTarget,EXECUTE_READ);
SHOWMASK(dwTarget,EXECUTE_READWRITE);
SHOWMASK(dwTarget,EXECUTE_WRITECOPY);
SHOWMASK(dwTarget,NOACCESS);
}
//遍历整个虚拟内存并对用户显示其属性的工作程序的方法
voidWalkVM(HANDLEhProcess)
{
//首先,获得系统信息
SYSTEM_INFOsi;
:
:
ZeroMemory(&si,sizeof(si));
:
:
GetSystemInfo(&si);
//分配要存放信息的缓冲区
MEMORY_BASIC_INFORMATIONmbi;
:
:
ZeroMemory(&mbi,sizeof(mbi));
//循环整个应用程序地址空间
LPCVOIDpBlock=(LPVOID)si.lpMinimumApplicationAddress;
while(pBlock { //获得下一个虚拟内存块的信息 if(: : VirtualQueryEx( hProcess,//相关的进程 pBlock,//开始位置 &mbi,//缓冲区 sizeof(mbi))==sizeof(mbi))//大小的确认 { //计算块的结尾及其大小 LPCVOIDpEnd=(PBYTE)pBlock+mbi.RegionSize; TCHARszSize[MAX_PATH]; : : StrFormatByteSize(mbi.RegionSize,szSize,MAX_PATH); //显示块地址和大小 std: : cout.fill('0'); std: : cout< : hex< : setw(8)<<(DWORD)pBlock<<"-" < : hex< : setw(8)<<(DWORD)pEnd <<(strlen(szSize)==7? "(": "(")< //显示块的状态 switch(mbi.State) { caseMEM_COMMIT: std: : cout<<",Committed"; break; caseMEM_FREE: std: : cout<<",Free"; break; caseMEM_RESERVE: std: : cout<<",Reserved"; break; } //显示保护 if(mbi.Protect==0&&mbi.State! =MEM_FREE) { mbi.Protect=PAGE_READONLY; } ShowProtection(mbi.Protect); //显示类型 switch(mbi.Type) { caseMEM_IMAGE: std: : cout<<",Image"; break; caseMEM_MAPPED: std: : cout<<",Mapped"; break; caseMEM_PRIVATE: std: : cout<<",Private"; break; } //检验可执行的影像 TCHARszFilename[MAX_PATH]; if(: : GetModuleFileName( (HMODULE)pBlock, szFilename, MAX_PATH)>0) { //除去路径并显示 : : PathStripPath(szFilename); std: : cout<<",Module: "< } std: : cout< : endl; //移动块指针以获得下一个块 pBlock=pEnd; } } } voidmain() { //遍历当前进程的虚拟内存 : : WalkVM(: : GetCurrentProcess()); } 清单2中显示一个WalkVM()函数开始于某个进程可访问的最低端虚拟地址处,并在其中显示各块虚拟内存的特性。 虚拟内存中的块由VirtualQueryEx()APl定义成连续块或具有相同状态(自由区、已调配区等)的内存,并分配以一组统一的保护标志(只读、可执行等)。 回答下列问题: 1)分析运行结果 按committed、reserved、free等三种虚拟地址空间分别记录实验数据,其中“描述”是指对该组数据的简单描述,例如,对下列一组数据: 00010000—00012000<8.00KB>Committed,READWRITE,Private可描述为: 具有READWRITE权限的已调配私有内存区。 将系统当前的自由区(free)虚拟地址空间填入表1中。 (表课可以自己画) 表1实验记录 地址 大小 虚拟地址 空间类型 访问权限 描述(type) free free free free free free free free free free free free free free free free free free free free free free free free free 将系统当前的已调配区(committed)虚拟地址空间填入表2中。 表2实验记录 地址 大小 虚拟地址 空间类型 访问权限 描述(type) committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed committed 将系统当前的保留区(reserved)虚拟地址空间填入表3中。 表3实验记录 地址 大小 虚拟地址 空间类型 访问权限 描述(type) reserved reserved reserved reserved reserved reserved reserved reserved reserved reserved 2)从上述输出结果,对照分析程序,请简单描述程序运行的流程: ____________________________________________________________________ ________________________________________________________________________ ________________________________________________________________________ ________________________________________________________________________ 3)实验总结 (根据实验结果及自己查阅相关资料写出VirtualAlloc()函数的作用,各个参数的可能值及含义。 写出对虚拟内存的认识) 补充知识: 出现“虚拟内存不够”的几个可能 1、感染病毒 有些病毒发作时会占用大量内存空间,导致系统出现内存不足的问题。 赶快去杀毒,升级病毒库,然后把防毒措施做好! 2、虚拟内存设置不当 虚拟内存设置不当也可能导致出现内存不足问题,一般情况下,虚拟内存大小为物理内存大小的2倍即可,如果设置得过小,就会影响系统程序的正常运行。 重新调整虚拟内存大小以WinXP为例,右键点击“我的电脑”,选择“属性”,然后在“高级”标签页,点击“性能”框中的“设置”按钮,切换到“高级”标签页,然后在“虚拟内存”框中点击“更改”按钮,接着重新设置虚拟内存大小,完成后重新启动系统就好了。 3、系统空间不足 虚拟内存文件默认是在系统盘中,如WinXP的虚拟内存文件名为“pagefile.sys”,如果系统盘剩余空间过小,导致虚拟内存不足,也会出现内存不足的问题。 系统盘至少要保留300MB剩余空间,当然这个数值要根据用户的实际需要而定。 用户尽量不要把各种应用软件安装在系统盘中,保证有足够的空间供虚拟内存文件使用,而且最好把虚拟内存文件安放到非系统盘中。 4、因为SYSTEM用户权限设置不当 基于NT内核的Windows系统启动时,SYSTEM用户会为系统创建虚拟内存文件。 有些用户为了系统的安全,采用NTFS文件系统,但却取消了SYSTEM用户在系统盘“写入”和“修改”的权限,这样就无法为系统创建虚拟内存文件,运行大型程序时,也会出现内存不足的问题。 问题很好解决,只要重新赋予SYSTEM用户“写入”和“修改”的权限即可,不过这个仅限于使用NTFS文件系统的用户。 虚拟内存的优化 1.启用磁盘写入缓存 在“我的电脑”上单击鼠标右键选择“属性->硬件”,打开设备管理器找到当前正在使用的硬盘,单击鼠标右键选择属性。 在硬盘属性的的“策略”页中,打开“启用磁盘上的写入缓存”。 这个选项将会激活硬盘的写入缓存,从而提高硬盘的读写速度。 不过要注意一点,这个功能打开后,如果计算机突然断电可能会导致无法挽回的数据丢失。 因此最好在有UPS的情况下再打开这个功能。 当然,如果你平常使用计算机时不要进行什么重要的数据处理工作,没有UPS也无所谓,这个功能不会对系统造成太大的损失。 2.打开UltraMDA 在设备管理其中选择IDEATA/ATAPI控制器中的“基本/次要IDE控制器”,单击鼠标右键选择“属性”,打开“高级设置”页。 这里最重要的设置项目就是“传输模式”,一般应当选择“DMA(若可用)”。 3.配置恢复选项 WindowsXP运行过程中碰到致命错误时会将内存的快照保存为一个文件,以便进行系统调试时使用,对于大多数普通用户而言,这个文件是没有什么用处的,反而会影响虚拟内存的性能。 所以应当将其关闭。 在“我的电脑”上单击鼠标右键,选择“属性->高级”,在“性能”下面单击“设置”按钮,在“性能选项”中选择“高级”页。 这里有一个“内存使用”选项,如果将其设置为“系统缓存”,WindowsXP将使用约4MB的物理内存作为读写硬盘的缓存,这样就可以大大提高物理内存和虚拟内存之间的数据交换速度。 默认情况下,这个选项是关闭的,如果计算机的物理内存比较充足,比如256M或者更多,最好打开这个选项。 但是如果物理内存比较紧张,还是应当保留默认的选项。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 虚拟 存储器