《windows核心编程》 在应用程序中使用虚拟内存
Microsoft Windows 提供了以下三种机制来对内存进行操控:
- 虚拟内存 最适合用来管理大型对象数组或大型结构数组
- 内存映射文件 最适合用来管理大型数据流(通常是文件),以及在同一台机器上运行多个进程之间共享数据
- 堆 最适合管理大量小型对象
本篇只讨论第一种方式 虚拟内存。
15.1 预订地址空间区域
可以使用VirtualAlloc函数来预订进程中的地址空间区域
LPVOID WINAPI VirtualAlloc(
__in_opt LPVOID lpAddress,
__in SIZE_T dwSize,
__in DWORD flAllocationType,
__in DWORD flProtect
);
lpAddress :想要预订地址空间的哪一块,如果要在进程地址空间第50MB的地方分配区域。我们要传52 428 800(50*1024*1024)给pvAddress参数。系统始终按分配粒度的整数倍来分配的因此如果我们想要在19668992(300*65536+8192)的地方预订区域,那么系统会向下取整到64整数倍,也就是19660800(300*65536)然后取整后的地址预订区域。如果VirtualAlloc能满足我们的要求,那么它会预订一块区域并返回该区域的基地址。如果我们还给pvAddesss指定了参数,那么,它的返回值就等于我们传给pvASddress参数值向下取整到64KB的整数倍dwSize: 指定我们想要分析区域的大小,以字节为单位。由于系统始终都根据cpu页面大小整数倍来预订区域,因此如果我们的页面大小为4KB,8KB或16KB的机器上预订62 KB的区域的话,那么最终得到的区域大小为64KBflAllocationType:是预订区域还是调拨物理存储器,如果是预订就要传 MEM_RESERVE为参数如果打算预订一块区域,并且用很长时间,那我们可能会希望系统从尽可能高的内存地址来预订。这样可以防止进程地址空间的中间预订区域,从而避免可能会引起内存碎片。fdwProtect:给区域指定保护属性。如果应用程序在非统一内存访问的机器上运行,我们可以调用VirtualAllocExNuma函数来强制系统在某个节点的物理内存中分配一部分虚拟内存
15.2 给区域调拨物理存储器、
在预了区域之后,我们还需要给给区域调拨物理存储器,这样才能访问其中的内存地址。系统会从页交换文件中来调拨物理存储器给区域。在调拨物理存储器时,起始地址始终都是页面大小的整数倍,整个大小也是页面大小的整数倍调拨物理存储器,我们必须再次调用VirtualAlloc。但这次我们会传 MEM_COMMIT来作为第二个参数fdwAllocationType的值在已预订的区域中,我们“必须”告诉VirtualAlloc要调拨多少物理存储器给哪里。这是通过pvAddress和dwSize来指定的。前者表示想要调拨物理存储器给哪个内存地址,后来表示物理存储器的数量。以字节为单位。
15.3 同时预订和调拨物理存储器
PVOID pvMem = VirtualAlloc(NULL,99*1024,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE)
15.4 何时调拨物理存储器
何时调拨物理存储器是一个问题,例如我们正在实现一个电子表格的程序,它支持200行,256。如果一个单元格是一个CELLDATA结构的话,如果这一个结构頕128字节,那么这个二维数组需要 200 * 256 * 128 的字节的物理存储器。那么如果一打开程序就去调拨,明显会頕用大量的物理存储器。尤其是因为用户经常只用一两个单元格的时候,那么这种调拨方法明显是浪费虚拟内存技术为我们提供了方案:1.预订一块足够大的区域来容纳CELLDATA数组。只预订根本不会消耗物理存储器
2.当用户某个单元格输入数据时,首先确定CELLDATA的内存地址。当然没有调拨,会引发访问违规
3.给第二步中的内存地址调拨足够的物理存储器。
4.设置CELLDATA结构成员的内容
虚拟内存技术存在一个问题是:我们必须确定什么时候需要调拨物理存储器。有以下四种方法来确定是否需要给区域中的某一部分调拨物理存储器
1.总是尝试调拨,这种该当的缺点是每次对CELLDATA进行修改时,要多调用一次 VirtualAlloc。
2.使用VirtualQuery来判断是否给CELLDATA调拨过了。这种方法其实比第一种方法还糟糕:由于额外调用了VirtuaQuery函数,它不但增加了程序的大小,而且还降低了程序的性能
3.记录哪些被调拨过。这样来实时调拨
4.使用结构化异常处理------最佳方案。让程序底图方法内存异常的时候,调拨。
15.5 撤销缺氧物理存储器及释放区域
要撤销调拨给区域的物理存储器,或是释放地址空间中的一整块区域,可以调用VirtualFree函数。如果进程不再需要访问区域中的物理存储器,那么我们只需要调用VirtaulFree一次,就能够释放整个区域以及调拨给该区域的物理存储。我们必须传MEM_RELEASE给fdwFreeType来告诉系统撤销调拨给该区域的所有物理存储器,并释放区域。如果想要撤销区域的一部分,我们只需要给pvAddress传地址,然后dwSize传大小,fdwFreeType传MEM_DECOMMIT就行
15.5.1何时撤销调拨物理存储器
15.6 改变保护属性
15.7 改变物理存储器的内容
当我们修改物理存储页中的内容时,系统会尽量把改动保持在内存中。但是,当应用程序在运行的时候,系统可能需要从exe文件,或dll文件或页交换文件中载入新的页面到内存里。为了满足最近的载入请求,系统会在内存查找可用的页面,如果找到的页面已经被修改过,那么系统还必须将它们换出到页交换文件中。
Windows还提供了一种特性,一路使得应用程序能够提高中自身的性能-----这项特性就是重置物理存储器。重置物理存储器的意思是,我们告诉系统一个或几个物理存储页中的数据没有被修改过。如果系统正在查找一页闲置内存并且找到了一个修改过的页面,那么系统必须把该内存写入到页交换文件中。这个操作比较慢,会影响性能。对大多数应用程序来说,我们都希望系统把修改后的页面保存到页交换文件中。
但是,有些应用程序只需要在一小段时间内使用存储器,之后也不需要保留存储器中的内容。为了提高性能,应用程序可以告诉系统不要在页交换文件中保存指定存储器。这基本上是应用程序用来告诉系统一个页面未被修改过的一种方法。因此,如果系统决定将一个内存页挪作他用,好么它不会将页面内容保存到页交换文件中,这样提高了性能。为了重置存储器,应用程序应该调用VirtualAlloc函数,并在第三个参数中传MEM_RESET标志。
15.8 地址窗口扩展
地址窗口扩展特性:
1.允许应用程序以一种特殊的方式分配内存,操作系统保证不会将以这种方式分配的内存换出到磁盘上
2.允许应用程序访问比进程地址空间还要多的内存。
基本上 AWE提供了一种方式,可以让应用程序分配一块或多块内存。当一开始分配时,在进程的地址空间中是看不见这些内存块的应用程序然后预订地址空间区域,这就是地址窗口。应用程序然后调用一个函数,每调用一次把一块内存指定到该地址窗口。把内存块指定到地址窗口是非常快的。
//1.预订1MB地址空间
ULONG_PTR ulRAMBytes = * ;
PVOID pvWindow = VirtualAlloc(NULL,ulRAMBytes,
MEM_RESERVE | MEM_PHYSICAL ,PAGE_READWRITE); //2.得到当前平台的一个页面的大小
SYSTEM_INFO sinf;
GetSystemInfo(&sinf); //3.计算需要多少内存页
ULONG_PTR ulRAMPages = (ulRAMBytes + sinf.dwPageSize - ) / sinf.dwPageSize; //4.分配内存页数组、
ULONG_PTR * aRAMPages = (ULONG_PTR * ) new ULONG_PTR[ulRAMPages]; //5.分配物理存储器
AllocateUserPhysicalPages(GetCurrentProcess(),
&ulRAMPages,
aRAMPages); //6. 指定内存块指定给地址窗口
MapUserPhysicalPages(pvWindow,
ulRAMPages,
aRAMPages); //7.使用内存... //8.释放内存页块
FreeUserPhysicalPages(GetCurrentProcess(),
&ulRAMPages,
aRAMPages); VirtualFree(pvWindow,,MEM_RELEASE);
delete [] aRAMPages;
《windows核心编程》 在应用程序中使用虚拟内存的更多相关文章
- Windows核心编程:第14章 探索虚拟内存
Github https://github.com/gongluck/Windows-Core-Program.git //第14章 探索虚拟内存.cpp: 定义应用程序的入口点. // #inclu ...
- 《Windows核心编程系列》十三谈谈在应用程序中使用虚拟内存
在应用程序中使用虚拟内存 Windows提供了以下三种机制对内存进行操控: 一:虚拟内存.最适合来管理大型对象数据或大型结构数组. 二:内存映射文件.最适合用来管理大型数据流,以及在同一机 器上运行的 ...
- Windows核心编程 第十五章 在应用程序中使用虚拟内存
第1 5章 在应用程序中使用虚拟内存 Wi n d o w s提供了3种进行内存管理的方法,它们是: • 虚拟内存,最适合用来管理大型对象或结构数组. • 内存映射文件,最适合用来管理大型数据流(通常 ...
- 《Windows核心编程》第一讲 对程序错误的处理
一个Windows函数通常都有一个有意义的返回值类型,它标志着这个函数的运行状态,即函数运行成功与否.windows常用的函数类型如下图: 从系统内部来讲,当一个Windows函数检测到一个错误时,它 ...
- windows核心编程 第5章job lab示例程序 解决小技巧
看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里” 用process explorer程序查看 ...
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
- windows核心编程---第九章 同步设备IO与异步设备IO之同步IO
同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...
- windows核心编程---第八章 使用内核对象进行线程同步
使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...
- windows核心编程---第二章 字符和字符串处理
使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也 ...
- 《Windows核心编程》第5版 学习进度备忘
学习资源:<Windows核心编程>第5版 知识基础支持: 本书与<Windows程序设计>第5版珍藏版结合很好,二者重叠内容不多,二者互补性强,而且相关方面的优秀书籍 跳过的 ...
随机推荐
- V4L2 camera 驱动 capture测试程序【转】
转自:http://blog.csdn.net/kickxxx/article/details/6336346 在网上找了一个测试程序, 看了看,是根据capture.c修改的.测试步骤如下 . gc ...
- win2008服务器asp站点配置要点
Win2008服务器重装系统后,运行ASP站点(使用Access数据库)报N多错误,经过一小时总算解决,总结如下: 在win2008服务器上1. 本站点应用程序池改为启用32位.2. 本站点启用父路径 ...
- WinForm Control.Invoke&Control.BeginInvoke异步操作控件实例
参考:http://www.cnblogs.com/yuyijq/archive/2010/01/11/1643802.html 效果图: 实例(实验)代码: using System; using ...
- (4)C#工具箱-菜单和工具栏
1.ContextMenuStrip(右键菜单栏) 把contextMenuStrip控件拖到窗体上,会在窗体下面显示,点击控件在最上行显示菜单栏,可以任意设置.(运行以后不会在界面上显示,它需要预控 ...
- Python的扩展接口[1] -> 串口通信
串口通信 / Serial Communication 1 串口简介 / Serial Introduction 串行接口(Serial Interface)简称串口,通常为COM接口,数据发送方式为 ...
- 动态读取cron表达式
项目中在使用任务调度时往往会用到cron表达式,比如每五分钟执行一次,每天12点执行一次,每周四凌晨1点执行一次等.但是如果将cron表达式写死,往往不利于测试.解决方案:我们可以将cron表达式写入 ...
- 用SparkSQL构建用户画像
用SparkSQL构建用户画像 二. 前言 大数据时代已经到来,企业迫切希望从已经积累的数据中分析出有价值的东西,而用户行为的分析尤为重要. 利用大数据来分析用户的行为与消费习惯,可以预测商品的发展 ...
- Linux文本过滤常用命令(转)
01 cat命令 通常用来显示文本文件的内容 一般用来查看比较短的文本文件,因为其缓冲区有限 -s选项可以用来合并文件中多余的空行,多个空行将被压缩为一个空行; -n选项可以显示行号 -b选项可以跳过 ...
- ICA (独立成分分析)
介绍 独立成分分析(ICA,Independent Component Correlation Algorithm)简介 X=AS X为n维观测信号矢量,S为独立的m(m<=n)维未知源信号矢量 ...
- elasticsearch升级步骤
ES从1.2.1升级到1.4.0 升级步骤,基本上是按照官网的叙述来完成的,链接是:http://www.elasticsearch.org/guide/en/elasticsearch/refere ...