《Windows核心编程系列》应用程序中的虚拟内存
作者:网络转载 发布时间:[ 2013/1/8 15:51:37 ] 推荐标签:
Windows提供了以下三种机制对内存进行操控:
一:虚拟内存。适合来管理大型对象数据或大型结构数组。
二:内存映射文件。适合用来管理大型数据流,以及在同一机 器上运行的多个进程之间共享数据。
三:堆。适合用来管理大量的小型对象。
很多人都对VirtualAlloc和malloc 或new的区别不是很清楚,我也一样。搜索下了,发现这句话说的很清楚了:
VirtualAlloc要进入内核模式,算法特复杂,比较慢,而且分配粒度是4k,用来分配小块内存很浪费
malloc先用VirtualAlloc弄一大块内存,后面在堆上分配时不用进入内核模式,算法也简单些,而且分配粒度比较小
VirtualAlloc只能分配4KB为单位的页面,适合大型数据或者内存映射文件等用途。而堆的申请分配没有这个限制,更为灵活。
有的人嫌malloc还不够精简,于是又在堆上面开辟自己的内存池,更加轻量级
本文将主要介绍虚拟内存。
Windows提供了一些用来操纵虚拟内存 的函数,我们可以通过这些函数直接预订地址空间区域,并给这些预订的区域调拨来自页交换文件的物理存储器。
预定地址空间区域。
可以通过调用VirtualAlloc函数来运行:
PVOID VirtualAlloc(
PVOID pvAddress,
SIZE_T dwSize,
DWORD fdwAllocationType,
DWORD fdwProtect);
pvAddress是内存地址。用来告诉我们想要运行地址空间中的哪一块。
当传入NULL时,系统会自动找到一块闲置区域。
如果在pvAddress标识的内存块中找不到闲置区域,或闲置区域不够大函数将返回NULL。
如果VirtualAlloc能满足我们的要求,它会预定一块区域并返回该区域的基地址。
dwSize用来指定我们想要预订的区域大小。以字节为单位。 系统始终以cpu页面大小整数倍来预定区域。且起始地址是按照分配粒度64kB的整数倍来预定的。
fdwAllocationType用来告诉系统我们到底是要预订还是要调拨物理存储器。如果要预订区域可以传入:MEM_RESERVE。如果我们想让系统从尽可能高的内存地址来预定区域,必须传入NULL给pvAddress,同时对MEM_TOP_DOWN和MEM_RESERVE标志进行按位或操作。
fdwProtect给区域指定保护属性。区域的保护属性对调拨给该区域的物理存储器不起任何作用。无论指定何种保护属性,只要还未给该区域调拨物理存储器都会导致访问违规。
预订时指定的属性应该跟调拨时指定的属性相同,这样系统内部处理效率会更高。
调拨物理存储器
预定区域后还需要给该区域调拨物理存储器。系统会从页交换文件中调拨物理存储器给该区域。在调拨物理存储器时,起始地址和区域大小始终都是页面大小的整数倍。调拨物理存储器同样需要调用VirtualAlloc。但这次我们需要传入MEM_COMMIT来作为fdwAllocationType的值。
pvAddress标识要调拨物理存储器的区域的起始地址。
dwSize表示物理存储器的大小。以字节为单位。我们并不需要给整个区域都调拨物理存储器。
有了起始地址和大小可以标识一段区域。
同时预定和调拨物理存储器
有时我们项同时预定区域并给该区域调拨物理存储器。同样需要调用VirtualAlloc。但是MEM_RESERVE要和MEM_COMMIT按位或并将它们传给fdwAllocationType。此时系统会为整个区域调拨物理存储器。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11