对于Windows 32来说,系统会给每个进程4GB的地址空间,低端2GB($00000000-$7FFFFFFF)给用户支配;高端2GB($80000000-$FFFFFFFF)留给系统使用,这个4G的地址空间叫“虚拟地址表”,虚拟地址表不是真实的内存。
这个“虚拟地址表”上有4GB的空间,每个程序都有这样的一个表,但他们并不会冲突,这样就阻断了一个进程对另一个进程的访问,系统在需要的时候会把他们映射成具体的真实内存地址。
可以使用GlobalMemoryStatus来获取内存信息,获取后的信息放在TMemoryStatus结构体中。
_MEMORYSTATUS = record
dwLength: DWORD; {结构长度}
dwMemoryLoad: DWORD; {表示可用内存比例的一个整数, 100 表示内存都可用}
dwTotalPhys: DWORD; {物理内存总数}
dwAvailPhys: DWORD; {可用物理内存总数}
dwTotalPageFile: DWORD; {虚拟内存总数}
dwAvailPageFile: DWORD; {可用虚拟内存总数}
dwTotalVirtual: DWORD; {虚地址表中的地址总数}
dwAvailVirtual: DWORD; {虚地址表中可用的地址总数}
end;
TMemoryStatus = _MEMORYSTATUS;
在用户的2GB地址空间中,低端的0-$FFFF是用于空指针分配,高端的$7FFF0000-$7FFFFFFF用于进程的临界区,这两个地址都是禁止访问的。进程真正的私有空间地址是:$10000-$FFEFFFF。我们可以通过GetSystemInfo函数得到证实,函数返回TSystemInfo结构,结构中的lpMinimumApplicationAddress和lpMaximumApplicationAddress分别标识程序可以访问的最低与最高地址,通过GetSystemInfo还能得到一个内存相关的重要参数:页大小(PageSize),通常大小是4K,我们需要知道的是,用VirtualAlloc函数分配的内存就是PageSize(4K)为最小单位,加入我们用VirtualAlloc给一个整数分配内存,就会浪费4092个字节。