Window API (四)虚拟内存管理

来源:互联网 发布:linux退出命令 编辑:程序博客网 时间:2024/06/10 02:20

         进程的虚拟地址空间内存页面存在 3 种状态, 分别为空闲的 (free) 、 保留的(reserved)和提交的(Committed)具体见下表。大多数情况下,一页的大小是 4KB。

       

 

示例程序:


 

#include<windows.h>#include<stdio.h>int main(void){SIZE_T sizeVirtual = 4000;LPVOID lpRound = (LPVOID)0x100000FF;MEMORY_BASIC_INFORMATION mbi;LPVOID lpAddress = VirtualAlloc(lpRound,sizeVirtual,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);if(lpAddress == NULL){printf("VirtualAlloc error: %d\n",GetLastError());return 1;}printf("Alloc:MEM_COMMIT |MEM_RESERVE\n");LPSTR szString= "Marry Christmas and no over work!";CopyMemory(lpAddress,szString,lstrlen(szString));printf("VirtualAlloc success!\n The address is :0x%.8x,the contentis: %s\n",lpAddress,lpAddress);VirtualQuery(lpAddress,&mbi,sizeof(mbi));printf("Get the Information from Virtual Query:\n""BaseAddress:0x%.8x\nAllocationBase:0x%.8x\n""AllocationProtect:0x%.8x\nRegionSize:%u\n""State:0x%.8x\nProtect:0x%.8x\nType:0x%.8x\n",mbi.BaseAddress,mbi.AllocationBase,mbi.AllocationProtect,mbi.RegionSize,mbi.State,mbi.Protect,mbi.Type);printf("Free: DECMMIT\n");if(!VirtualFree(lpAddress,sizeVirtual,MEM_DECOMMIT)){printf("VIrtualFree error: %d",GetLastError());return 1;}VirtualQuery(lpAddress,&mbi,sizeof(mbi));printf("Get the Information from Virtual Query:\n""BaseAddress:0x%.8x\nAllocationBase:0x%.8x\n""AllocationProtect:0x%.8x\nRegionSize:%u\n""State:0x%.8x\nProtect:0x%.8x\nType:0x%.8x\n",mbi.BaseAddress,mbi.AllocationBase,mbi.AllocationProtect,mbi.RegionSize,mbi.State,mbi.Protect,mbi.Type);printf("Free:RELEASE\n");if(!VirtualFree(lpAddress,0,MEM_RELEASE)){printf("VirutalFree error: %d",GetLastError());return 1;}return 0;}

 

运行结果:

 

Alloc:MEM_COMMIT |MEM_RESERVEVirtualAlloc success! The address is :0x10000000,the contentis: Marry Christmas and no over work!Get the Information from Virtual Query:BaseAddress:0x10000000AllocationBase:0x10000000AllocationProtect:0x00000004RegionSize:8192State:0x00001000Protect:0x00000004Type:0x00020000Free: DECMMITGet the Information from Virtual Query:BaseAddress:0x10000000AllocationBase:0x10000000AllocationProtect:0x00000004RegionSize:4096State:0x00002000Protect:0x00000000Type:0x00020000Free:RELEASE


 

      注意分配时指定的地址和大小与分配后地址和大小的变化。在分配时, 虽然为VirtualAlloc指定的分配地址为 0xl00000FF,大小为 4000 (0xFA0),但是分配完成后,VirtualAlloc 返回的地址是和通过 VirtualQurey 函数获得的起始地址为 0x10000000,大小 8192。产生这种变化的原因是: 
      0xl00000FF (lpAddress) ~ 0x1000109F (lpAddress+ dwSize= 0xl00000FF+ 0xFA0= 0x1000109F)的内存地址跨越了两个虚拟内存分页 0xl0000000~0xl000IFFF,是VirtualAlloc 进行自动对齐的结果,这就是虚拟内存分配的对齐机制。
    再来分析一下 VirtualQuery 获得的其他信息的含意,在内存分页处于已提交状态时和处于保留状态时,状态( State)分别为 0x1000 和 0x2000,保护属性(Protect)分别为 0x4和 0x0,分配时的保护属性(AllocationProtect)都是 0x4,类型均为 0x20000。在 winnt.h头文件中能找到这些常量的定义:
    

    #define PAGE_READWRITE        0x04      ...........     #define MEM_PRIVATE         0x20000     ..........................    #define MEM_COMMIT           0x1000    #define  MEM_RESERVE         0x2000


         状态值为 0x2000 时,说明其为保留页面(也有可能是 MEM_ FREE 0x10000,说明是空闲页面)。保护属性为 0x04,说明是可读可写的,在保留状态时,其保护属性是 0x00,内存的类型值有几种可能,分别为 MEM IMAGE(0xl000000)、MEM MAPPED(0x40000)、MEM PRIVATE(0x20000),前两种说明内存是通过内存映射共享的,MEM PRIVE说明内存页面没有与其他进程共享。

 

    本篇博客出自  阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/7077605

 

 

原创粉丝点击