内存(包括虚拟内存)管理

来源:互联网 发布:pos机淘宝不能卖了 编辑:程序博客网 时间:2024/04/29 20:19

分配内存: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就好了,除非一开始就想给自己保留一大片空间。

释放内存:VirtualFree

该函数的功能是取消或者释放调用进程的虚地址空间页的一个区域,如果想释放一块调用VirtualAllocEx函数分配的内存(包括虚拟内存),就使用VirtualFreeEx函数.

参数说明:

LPVOID lpAddress, 要释放的页的区域的地址,如果dwFreeType指定为MEM_RELEASE且这个区域是被保留的话,那么这个地址就要指定为分配区域的首地址

  SIZE_T dwSize, 要释放页的大小,如果dwFreeType类型中包含了MEN_RELEASE(应该是MEM_RELEASE),则dwSize必须为0

  DWORD dwFreeType 类型说明

  MEM_DECOMMIT 取消VirtualAlloc提交的页

  MEM_RELEASE 释放指定页,如果指定了这个类型而dwSize为设置为0,则函数会调用失败

返回值:

如果调用成功,返回一个非0值
调用失败,返回0


原创粉丝点击