VirtualAlloc函数使用总结
如果我们的程序需要动态内存的话,则迟早会调用Win32函数VirtualAlloc。但是程序也可以不调用VirtualAlloc,而是直接调用Windows堆函数或者CRT堆函数。不过,知道VirtualAlloc如何工作,可以帮助我们更好地理解这些调用函数。
首先,必须知道保留(Reserved)内存和占用(Committed)内存的含义。当内存放保留时,一段连续虚拟地址空间被留出。例如,假如我们的程序要使用5 -MB内存块(称为区域),但并不是要马上全部使用,则我们可以调用VirtualAlloc函数,使用MEM_RESERVE分配类型参数。Windows会以64 KB为边界计算该区域的起始地址,并防止进程在同一个范围内为其他内存保留。我们可以指定区域的起始地址,但更常见的是让Windows为区域分配地址。此时除了地址分配外,其他什么也没发生。没有RAM被分配,也没有交换文件空间被保留出来。
当我们对内存的需求更迫切时,我们可以再次调用函数VirtualAlloc来占用被保留的内存,调用时使用MEM_COMMIT分配类型参数。现在,区域的起始和结束地址都被计算到4KB边界,对应的交换文件页和所要求的页表被留出来。内存块可以被指定为只读或者可读写。然而,仍然没有RAM被分配;只有当程序访问这部分内存时RAM内存才会被真正分配。如果在此之前内存没有被保留,那就不会有问题;如果在此之前内存被占用了的话,也不会有问题。所以原则是,在使用内存之前一定要先占用。
我们可以调用VirtualFree函数“收回”(decommit)占用的内存,使指定的页回到保留的状态。VirtualFree也能够释放保留的内存区域,但我们必须指定其基地址,这个基地址是在前面调用VirtualAlloc保留内存时获得的。
什么时候才要用到VirtualAlloc
在没有C运行库可用的时候,要用VirtualAlloc来申请内存。另外,VirtualAlloc还可对申请的内存有许多的控制。
1、可以保留地址空间但不是及分配内存,在需要的时候再分配;
2、可以声明分配的内存不使用分页;
3、可以指定内存在尽可能高的地址上分配;
4、指定内存的读、写、执行属性和内存保护;
5、禁止所分配内存被高速缓存。
我的理解是在 malloc,new的内部实际上还是调用了virtualalloc,virtualalloc是可以自己控制页面的保留,提交,释放的实际的。实际上我们申请的内存没有使用的时候,都是被放在内存页面中,在使用的时候才会被切换到真正的物理存储器里。对于c++程序员来说 一般情况使用malloc,new就好了,除非一开始就想给自己保留一大片空间。