windows虚拟内存机制

在windows系统中个,每个进程拥有自己独立的虚拟地址空间(Virtual Address Space)。这一地址空间的大小与计算机硬件、操作系统以及应用程序都有关系。

对于32位程序来说,最多能使用2GB空间(0x00010000-0x7FFEFFFF)。为了获得3GB的地址空间,在不同的windows系统中可以按照如下方法来进行扩充。

1.操作系统方面

① 32位windowsXP

② 32位win7 -- 管理员权限执行命令:bcdedit /set increaseuserva 3072来开启

③ 64位win7 -- 对32位程序默认开启3GB,无需额外设置

2.应用程序方面

无论是32位还是64位windows若要让32位程序能使用3GB内存,必须在链接时加上参数: /LARGEADDRESSAWARE

进程地址空间区段

注:进程地址空间在低地址,操作系统内核在高地址

进程地址空间分布(以2GB为例)

Windows系统在进程空间中专门划出一块0x70000000 - 0x80000000(共256MB)区域,用于映射这些常用的系统DLL(如kernel32.dll、ntdll.dll等)

对系统DLL的默认基地址进行调整,防止加载时冲突,触发ReBasing(重定基地址)

注:基地址必须对齐到分配粒度(64KB)

Win7下,exe在PE文件中基地址为0x400000,DllPrj.dll的基地址为0x10000000且该地址未被其他dll占用;但实际exe被映射到0xEC0000,DllPrj.dll被映射到0x535A0000

生成exe和dll模块时,链接时使用了参数/DYNAMICBASE(启用动态基地址)

注:地址空间布局随机化, Address space layout randomization (ASLR):防范恶意程序对已知地址进行攻击

windows内存分配过程可细化为以下3个要点:

① 保留一段虚拟内存地址空间:从进程的4GB中保留一段地址空间。// 带MEM_RESERVE参数的VirtualAlloc函数

起始地址必须是系统分配粒度的整数倍(64KB),大小必须是系统页面大小的整数倍(4KB)。

② 提交一段虚拟内存地址空间:将进程已保留的一段地址空间映射机器的虚拟内存上。// 带MEM_COMMIT参数的VirtualAlloc函数

起始地址和大小都必须是页面大小的整数倍(4KB)。

③ 将虚拟内存地址空间映射到物理内存页(RAM):在访问进程提交的页面被访问时,通过缺页中断(又名页缺失、页面错误, PageFault)机制来真正分配物理内存页,同时修改对应页面的地址空间映射关系。

注1:在程序中所访问的地址都必须是保留并提交的虚拟内存地址

注2:可以使用VirtualFree来释放保留或提交的虚拟内存地址空间

内存指标概念

虚拟内存:

Private Bytes  // 进程Committed的虚拟内存字节数    对应win7任务管理器中的【提交大小】,资源管理器中的【提交】

Peak Private Bytes  // 进程Committed的虚拟内存的最高峰字节数

Virtual Size // 进程Reserved的虚拟地址空间字节数

Page Faults  // 发生过的缺页中断次数    对应win7任务管理器中的【页面错误】

物理内存:

Working Set = WS Private + WS Shareable  // 进程占用物理内存总字节数  对应win7任务管理器中的【工作设置(内存)】,资源管理器中的【工作集】

WS Private // 进程独享的物理内存字节数(如:堆内存+栈内存+cow机制创建的内存)   对应win7任务管理器中的【内存(专用工作集)】,资源管理器中的【专用】

WS Shareable  // 进程可与其他进程共享的物理内存字节数(如:exe及dll代码段、数据段等)  对应win7资源管理器中的【可共享】

WS Shared  // 进程已与其他进程共享的物理内存字节数,WS Shared<=WS Shareable

// 若只启动一个exe实例,那么exe的代码段、数据段等不会被共享,因而就不统计在WS Shared中

Peak Working Set // 物理内存的最高峰字节数  对应win7任务管理器中的【峰值工作设置(内存)】

注:无论是虚拟内存还是物理内存下的各个指标,都是通过统计用户态的那部分占用

页交换文件

页交换文件(Page File):一般被用作可写物理内存页的后备存储器。Windows下该文件名为pagefile.sys,位于各盘的根目录中。

可以根据机器的软硬件状况来设置页交换文件的大小,甚至关闭页交换文件的使用。

 

页出(Page Out):当物理内存不够时,系统会将一些不经常使用且有后备的物理内存页释放,并将虚拟地址映射关系指向后备。

①以页交换文件(如:堆、栈等)为后备:在页交换文件中分配空间,并拷贝内容到其中后再释放

②以内存映射文件(如:exe、dll等)为后备:直接释放

页入(Page In):当系统读取某个虚拟内存地址,而该地址所在的页不在物理内存页中时,将产生一个缺页中断,

告诉系统从页交换文件或者内存映射文件中取回包含该地址的虚拟内存页(即:将内容拷回到物理内存页,并建立新的虚拟地址映射到物理内存页上,然后释放页交换文件中对应部分的空间) 。

写时复制机制

写时复制机制(copy on write, COW):当WRITECOPY属性内存页面被修改时,会触发内存页拷贝,以此来节省物理内存和页交换文件的占用。

注:系统在映射exe或dll文件时会把数据页指定为PAGE_WRITECOPY属性,代码页指定为PAGE_EXECUTE_WRITECOPY属性

具体过程:

① 当进程对内存页执行修改操作时,系统会找一个闲置的物理内存页,并拷贝所有内容到新页上,然后标记新页的后备存储器为页交换文件,最后将进程的虚拟内存页指向新的物理内存页。

② 经过上述步骤,进程就可以使用自己副本了,修改在新的物理页上进行,而不对原来的内存页产生任何影响。

重定基地址

重定基地址(Rebasing):模块装载时,如果目标地址被占用或基于安全考虑,系统会根据模块的所需地址空间的大小为其分配一个新的基地址,并将模块装载到该基地址处。

问题:

①  一旦发生了Rebasing,当模块映射时,要对重定位表中所有页进行地址修正。

② 系统修正这些地址的页面时,会触发写时复制机制。

地址空间布局随机化(Address space layout randomization,ASLR)

微软在Vista系统中引入了名为ASLR的技术,模块每次会被加载到随机位置(伪随机),防范恶意程序对已知地址进行攻击。

ASLR不仅对模块地址做了随机处理,还对堆、栈、进程环境块(Process Environment Block, PEB)、线程环境块(Thread Environment Block, TEB)的地址也进行了随机化。

ASLR技术将Rebasing放到内核中进行处理,意味着可以在系统范围上(原来只能在进程范围内),最大程度上减少Rebasing的发生,从而节省物理内存和页交换文件的使用。

PE文件装载

注:映射必须以页面(4KB)为单位,并按照页边界进行对齐

执行完映射后,绝大部分指令和数据都还没有被装入物理内存中。装载过程是随着程序的执行动态进行的。

具体过程:cpu在访问指令和数据时,发现该地址所在的页不在物理内存页中时,会触发缺页中断,此时系统会找一个闲置的物理内存页,并将内容从后备中(映像文件或页交换文件中)载入到该物理内存页中。

时间: 2024-10-11 12:58:37

windows虚拟内存机制的相关文章

windows虚拟内存管理

内存管理是操作系统非常重要的部分,处理器每一次的升级都会给内存管理方式带来巨大的变化,向早期的8086cpu的分段式管理,到后来的80x86 系列的32位cpu推出的保护模式和段页式管理.在应用程序中我们无时不刻不在和内存打交道,我们总在不经意间的进行堆内存和栈内存的分配释放,所以内存是我们进行程序设计必不可少的部分. CPU的内存管理方式 段寄存器怎么消失了? 在学习8086汇编语言时经常与寄存器打交道,其中8086CPU采用的内存管理方式为分段管理的方式,寻址时采用:短地址 * 16 + 偏

(转载)Windows消息机制

文章出处:http://www.cnblogs.com/watsonyin/archive/2005/12/12/295536.html Windows消息机制 Windows操作系统最大的特点就是其图形化的操作界面,其图形化界面是建立在其消息处理机制这个基础之上的.如果不理解Windows消息处理机制,肯定无法深入的理解Windows编程.可惜很多程序员对Windows消息只是略有所闻,对其使用知之甚少,更不了解其内部实现原理,本文试着一步一步向大家披露我理解的Windows消息机制.可以说,

Windows 消息机制

Windows 消息机制 Windows是一个消息驱动的操作系统. 如绘制窗体的消息 WM_PAINT. 结构体定义: 消息分类-发送途径 队列消息. Windows为每一个执行中的程序维护一个消息队列.由应用程序自己取出,如WM_TIMER. 非队列消息. 此类消息来自特定的Windows函数,如UpdateWindow()函数直接向窗体处理函数发送WM_PAINT重绘消息. 消息分类-发送者 系统消息.是提前定义的UINT常量. 用户消息. 通过RegisterWindowMessage()

windows消息机制(MFC)

windows消息机制(MFC) 消息分类与消息队列 Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型, 而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据的含义也不一样. time表示产生消息的时间,pt表示产生消息时鼠标的位置. 按照类型,Windows将消息分为: (0) 消息ID范围 系统定义消息ID范围:[0x0000, 0x03ff]用户自定义的消息ID范围: WM_USER: 0x0400-0x7FFF 

windows消息机制

一. windows消息机制处理流程 (1)windows会为每一个正在执行的windows应用程序建立一个消息队列,即应用程序队列,用来存放该程序可能创建的各种窗口的消息. 当应用程序发生事件后,windows将事件转化为消息并将消息放入应用程序的消息队列中. (2)应用程序通过GetMessage从消息队列中检索事件消息并把他们分发到相应窗口的消息处理函数中. while(GetMessage(&msg, NULL, 0, 0)) { // 将虚拟键消息转换为字符消息 TranslateMe

005 windows消息机制

#windows消息机制 新建第一个Win32应用程序 VS2015 新建项目 Win32应用程序 // Win32WindowDemo.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32WindowDemo.h" #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 WCHAR szTitle[MAX_LOADSTRING]; // 标

收藏:Windows消息机制

百度百科介绍的windows消息机制也不错:http://baike.baidu.com/view/672379.htm Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视化的交互方式,窗口是由线程(Thread)创建的.Windows系统通过消息机制来管理交互,消息(Message)被发送,保存,处理,一个线程会维护自己的一套消息队列(Message Queue),以保持线程间的独占性.队列的特点无非是先进先出,这种机制可以实现一种异步的需求响应过程. 消息的是什么

从0 开始 WPF MVVM 企业级框架实现与说明 ---- 第一讲 WPF中 windows消息机制

谈到桌面应用程序,我们第一反应就是它的消息机制是怎么处理的,那么我们就先聊聊这个windows消息机制 谈起“消息机制”这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派发给特定的窗口,实际上消息是被Post到特定窗口所在线程的消息队列,应用程序的消息循环再不断的从消息队列当中获取消息,然后再派发给特定窗口类的窗口过程来处理,在窗口过程中完成一次用户交互. 其实,WPF的底层也是基于Win

虚拟内存机制

1.为什么要有虚拟内存在早期的计算机中,是没有虚拟内存的概念的.我们要运行一个程序,会把程序全部装入内存,然后运行.当运行多个程序时,经常会出现以下问题:1)进程地址空间不隔离,没有权限保护.由于程序都是直接访问物理内存,所以一个进程可以修改其他进程的内存数据,甚至修改内核地址空间中的数据.2)内存使用效率低当内存空间不足时,要将其他程序暂时拷贝到硬盘,然后将新的程序装入内存运行.由于大量的数据装入装出,内存使用效率会十分低下.3)程序运行的地址不确定因为内存地址是随机分配的,所以程序运行的地址