page1of9操作系统2015Windows虚拟内存分配问题张懿1问题描述使用Win32API函数,编写一个包含两个线程的进程,一个线程用于模拟内存分配活动,一个线程用于跟踪第一个线程的内存行为。要求模拟的操作包括保留一个区域、提交一个区域、回收一个区域、释放一个区域,以及锁定与解锁一个区域。跟踪线程要输出每次内存分配操作后的内存状态。通过对内存分配活动的模拟和跟踪的编程实现,从不同侧面对Windows对用户进程的虚拟内存空间的管理、分配方法,对Windows分配虚拟内存、改变内存状态,以及对物理内存和页面文件状态查询的API函数的功能、参数限制、使用规则进一步有所了解。同时了解跟踪程序的编写方法。2实验环境本实验在Windows8.1环境下实现。3解决思路为了实现两个进程的同步,设置一对信号量trac和allo,初始值为零。Allocator线程等待allo信号量,Tracker线程释放一个allo信号量后开始等待trac信号量。而Allocator线程每进行一项内存操作就释放trac信号量,然后继续等待allo信号量以继续操作。对于内存状态的输出,函数VirtualQuery可以返回一个指向MEMORYBASICINFORMATION结构体的指针,但其中的信息是以宏定义表示的,不方便阅读。为了能够方便的了解内存的信息,我们应该将宏转成字符信息,所以定义InfoConvert函数进行信息转换。使用GetSystemInfo函数可以获得该机器上有关的信息,如处理器数,页大小以及地址范围等。通过VirtualAlloc函数,选择不同参数可以保留或提交一个区域。通过VirtualLock和VirtualUnlock可以锁定、解锁内存区域。VirtualFree用于回收、释放内存区域。本程序结构为主函数建立Allocator和Tracker线程,两线程通过一对信号量进行同步。主线程等待全部操作完成后由Tracker释放的nished信号,最后关闭线程。每个线程执行的程序的代码如下:1page2of9操作系统2015CODE1:Allocator线线线程程程DWORDWINAPIAllocator(LPVOIDlpParam){//reserveif(WaitForSingleObject(allo,INFINITE)==WAIT_OBJECT_0){memPtr=VirtualAlloc(NULL,pageSize,MEM_RESERVE,PAGE_READWRITE);coutReserve:endl;coutMemoryAddress:memPtrendl;ReleaseSemaphore(trac,1,NULL);}//commitif(WaitForSingleObject(allo,INFINITE)==WAIT_OBJECT_0){coutCommit:endl;memPtr=VirtualAlloc(memPtr,pageSize,MEM_COMMIT,PAGE_READWRITE);ReleaseSemaphore(trac,1,NULL);}//lockif(WaitForSingleObject(allo,INFINITE)==WAIT_OBJECT_0){coutLock:endl;VirtualLock(memPtr,pageSize);ReleaseSemaphore(trac,1,NULL);}//unlockif(WaitForSingleObject(allo,INFINITE)==WAIT_OBJECT_0){coutUnlock:endl;VirtualUnlock(memPtr,pageSize);ReleaseSemaphore(trac,1,NULL);}//recycleif(WaitForSingleObject(allo,INFINITE)==WAIT_OBJECT_0){coutRecycle:endl;VirtualFree(memPtr,pageSize,MEM_DECOMMIT);ReleaseSemaphore(trac,1,NULL);}//releaseif(WaitForSingleObject(allo,INFINITE)==WAIT_OBJECT_0){coutRelease:endl;VirtualFree(memPtr,0,MEM_RELEASE);ReleaseSemaphore(trac,1,NULL);}return0;}2page3of9操作系统2015CODE2:Tracker线线线程程程//getmemoroyinformationandprintDWORDWINAPITracker(LPVOIDlpParam){SYSTEM_INFOinfo;GetSystemInfo(&info);//getinformationaboutcurrentdevicecoutHardwareInformation:endl;coutProcessorNumber:info.dwNumberOfProcessorsendl;coutProcessorType:info.dwProcessorTypeendl;coutMask:info.dwActiveProcessorMaskendl;coutPageSize:info.dwPageSizeendl;coutMinimumAddress:info.lpMinimumApplicationAddressendl;coutMaximumAddress:info.lpMaximumApplicationAddressendlendl;MEMORY_BASIC_INFORMATIONlpBuffer;memory_information_simumemInfo;for(inti=0;i6;i++){ReleaseSemaphore(allo,1,NULL);if(WaitForSingleObject(trac,INFINITE)==WAIT_OBJECT_0){VirtualQuery(memPtr,&lpBuffer,sizeof(lpBuffer));//RetrieveinformationaboutthepagesmemInfo=InfoConvert(lpBuffer);coutBaseAddress:memInfo.base_addressendl;coutAllocationBase:memInfo.allocation_baseendl;coutAllocationProtect:memInfo.allocation_protectendl;coutRegionSize:memInfo.region_sizeendl;coutState:memInfo.stateendl;coutProtect:memInfo.protectendl;coutType:memInfo.typeendl;coutendl;}}ReleaseSemaphore(finished,1,NULL);return0;}CODE3:InfoConvert函函函数数数memory_information_simuInfoConvert(MEMORY_BASIC_INFORMATION&lpBuffer){memory_information_simuinfo={};info.allocation_base=lpBuffer.AllocationBase;info.base_address=lpBuffer.BaseAddress;info.region_size=lpBuffer.RegionSize;switch(lpBuffer.AllocationProtect){casePAGE_EXECUTE:info.allocation_protect=execute;break;casePAGE_EXECUTE_READ:info.allocation_protect=executeread;break;3page4of9操作系统2015casePAGE_EXECUTE_READWRITE:info.allocation_protect=executereadwrite;break;casePAGE_EXECUTE_WRITECOPY:info.allocation_protect=executewritecopy;break;casePAGE_GUARD:info.allocation_protect=guard;break;casePAGE_NOACCESS:info.allocation_protect=noaccess;break;casePAGE_NOCACHE:info.allocation_protect=nocache;break;casePAGE_READONLY:info.allocation_protect=readonly;break;casePAGE_READWRITE:info.allocation_protect=readwrite;break;casePAGE_WRITECOPY:info.allocation_protect=writecopy;break;casePAGE_WRITECOMBINE:info.allocation_protect=writecombine;break;default:info.allocation_protect=callerdoesnothaveaccess;}switch(lpBuffer.Protect){casePAGE_EXECUTE:info.protect=execute;break;casePAGE_EXECUTE_READ:info.protect=executeread;break;casePAGE_EXECUTE_READWRITE:info.protect=executereadwrite;break;casePAGE_EXECUTE_WRITECOPY:info.protect=executewritecopy;break;casePAGE_GUARD:info.protect=guard;break;casePAGE_NOACCESS:info.protect=noaccess;break;casePAGE_NOCACHE:info.protect=nocache;break;casePAGE_READONLY:info.protect=readonly;break;casePAGE_READWRITE:info.protect=readwrite;break;casePAGE_WRITECOPY:info.protect=writecopy;break;casePAGE_WRITECOMBINE:info.protect=writecombine;break;default:info.protect=callerdoesnothaveaccess;}if(lpBuffer.State==MEM_COMMIT)info.state=memorycommit;elseif(lpBuffer.State==MEM_FREE)info.state=memoryfree;elseif(lpBuffer.State==MEM_RESERVE)info.state=memoryreserve;if(lpBuffer.Type==MEM_IMAGE)info.type=memoryimage;elseif(lpBuffer.Type==MEM_MAPPED)info.type=memorymapped;