现在的位置: 首页 > 综合 > 正文

《windows核心编程》读书笔记——在应用程序中使用虚拟内存

2013年10月04日 ⁄ 综合 ⁄ 共 1433字 ⁄ 字号 评论关闭

Microsoft Windows提供了三种机制来对内存进行操控。
 虚拟内存,最适合用来管理大型对象数组或大型结构数组。
 内存映射文件,最适合用来管理大型数据流,以及在同一机器上运行的多个进程之间共享数据。
 堆,最适合用来管理大量小型对象。

使用VirtualAlloc函数来预订分配进程中的地址空间区域:
LPVOID WINAPI VirtualAlloc(
  _In_opt_  LPVOID lpAddress,
  _In_      SIZE_T dwSize,
  _In_      DWORD flAllocationType,
  _In_      DWORD flProtect
);

lpAddress 是我们希望分配到的进程地址空间里的地址起始点,这个值会向上对齐到内存分配粒度,也就是64K(注意与页面大小的概念区分开);
dwSize 是我们希望分配到的进程地址空间里的块的大小,这个值会向上对齐到页面大小(在x84,x64上为4K,IA-64上为8K);
flAllocationType 是我们希望这个分配动作做的事情内容,正是这个值的多样性使这个函数如此复杂。最常用的有MEM_RESERVE预订进程地址空间里的块,MEM_COMMIT为进程空间里的块分配物理存储器,MEM_RESET释放已经分配的物理存储器但保留进程空间里的块为可用,MEM_TOP_DOWN告诉系统从进程空间地址的高地址方向完成这次分配。
flProtect 指定作用在进程空间里分配的这个块的保护属性。
 仍然要提醒,《核心编程》里面对于进程地址空间和物理存储器的使用比较混乱,会引起初学者不必要的疑惑,这里是明确两者是使用的。

 预订地址空间和分配物理存储器可以分别完成,也可以一起完成,都是使用VirtualAlloc函数完成。
 另外,Windows提供大页面分配物理存储器支持:使用GetLargePageMinimum函数返回的值为页面大小作为分配粒度,调用VitrualAlloc来分配物理存储器。(注:这个分配动作需要开页面分配权限,在本人机器上返回的页面大小居然是2G,进程地址空间里用户可用的地址空间总共就2G,因此是分配是返回资源不够。)
 
 使用VirtualFree来释放物理存储器及进程地址空间区域:
BOOL WINAPI VirtualFree(
  _In_  LPVOID lpAddress,
  _In_  SIZE_T dwSize,
  _In_  DWORD dwFreeType
);
 释放进程地址空间的区域的时候,也是需要把lpAddress对齐到分配粒度,dwSize对齐到页面大小,但需要注意释放的时候是大小向下对齐——因为向上对齐有可能释放到实际需要使用的区域。
 VirtualProtect函数可以改变程地址空间的区域保护属性,这个函数一般很少使用,可用于锁定程地址空间的区域以防其他代码段修改内容。
 重置物理存储器的内容这一节,说实话,我没明白设计这个有什么用,VirtualFree使用MEM_DECOMMIT参数一样能告知系统释放一块物理存储器但保留进程地址空间的块。书上也没把这两个内容做对比说明,这里是个疑问点,但不是重点。
 AWE地地址窗口的扩展,是可以配合大内存分配的内容一起使用在服务器上提高性能的功能。在我已经设置用户可以获取锁定页面权限的情况下,本机上跑的程序始终获取不到锁定内存的权限,AdjustTokenPrivileges始终返回拒绝访问错误。目前还没有进展。

 

抱歉!评论已关闭.