Window API (四)虚拟内存管理

时间:2023-01-02 09:22:54

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

        Window API (四)虚拟内存管理

 

示例程序:


 

#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_RESERVE
VirtualAlloc success!
The address is :0x10000000,the contentis: Marry Christmas and no over work!
Get the Information from Virtual Query:
BaseAddress:0x10000000
AllocationBase:0x10000000
AllocationProtect:0x00000004
RegionSize:8192
State:0x00001000
Protect:0x00000004
Type:0x00020000
Free: DECMMIT
Get the Information from Virtual Query:
BaseAddress:0x10000000
AllocationBase:0x10000000
AllocationProtect:0x00000004
RegionSize:4096
State:0x00002000
Protect:0x00000000
Type:0x00020000
Free: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