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来释放保留或提交的虚拟内存地址空间
内存指标概念
Total = Image + Mapped File + Shareable + Heap + Managed Heap + Stack + Private Data + Unusable
Image:exe、dll等可执行模块的代码段、数据段等
Mapped File:作为数据载入的内存映射文件
Shareable:进程间共享内存、消息等
Heap:malloc()、new、HeapAlloc()、LocalAlloc()创建出来的私有内存,由用户态堆管理器统一管理
Managed Heap:由GC管理的私有内存
Stack:线程栈
Private Data:由VirtualAlloc()创建出来的私有内存
Page Table:分配在内核态的页表
Unusable:起始地址以64KB对齐,导致一些无用的空闲内存地址空间
Free:空闲内存地址空间
-------------------------
Blocks:拥有内存块的个数
Largest:所有内存块中最大一个的size
虚拟内存:
Private Bytes // 进程Committed的虚拟内存字节数 对应VMMap的Private、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在访问指令和数据时,发现该地址所在的页不在物理内存页中时,会触发缺页中断,此时系统会找一个闲置的物理内存页,并将内容从后备中(映像文件或页交换文件中)载入到该物理内存页中。
windows虚拟内存机制的更多相关文章
- windows虚拟内存管理
内存管理是操作系统非常重要的部分,处理器每一次的升级都会给内存管理方式带来巨大的变化,向早期的8086cpu的分段式管理,到后来的80x86 系列的32位cpu推出的保护模式和段页式管理.在应用程序中 ...
- Windows消息机制
Windows的消息系统是由3个部分组成的: · 消息队列.Windows能够为所有的应用程序维护一个消息队列.应用程序必须从消息队列中获取消息,然后分派给某个窗口.· 消息循环.通过这个循环机制应用 ...
- Windows消息机制知识点总结
1.windows消息类型 以下四种,前三种是系统消息,范围在[0x0000, 0x03ff],第四种是用户自定义消息. 1.1 窗口消息 与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等.可以 ...
- 我对windows消息机制的理解(参考深入浅出MFC,欢迎批评指正!!)
以消息为基础,以事件驱动之 程序的进行依靠外部消息来驱动,即:程序不断等待任何可能的输入,然后做判断,然后再做适当的处理. 消息输入:操作系统捕获,以消息形式进入程序.(操作系统通过其USERS模块中 ...
- <Win32_1>深入浅出windows消息机制[转自crocodile_]
上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言.但是由于自身对windows的热爱,让我觉得c.c++语言才是我亲睐的编程语言 ...
- Windows消息机制要点
1. 窗口过程 每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wP ...
- 深入Delphi -- Windows 消息机制
http://www.txsz.net/xs/delphi/3/Windows%20%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.htm Windows 消息机制 by m ...
- 使用WMI来控制Windows目录 和windows共享机制
1.使用WMI来控制Windows目录 本文主要介绍如何使用WMI来查询目录是否存在.文件是否存在.如何建立目录.删除目录,删除文件.如何利用命令行拷贝文件,如何利用WMI拷贝文件 using Sys ...
- 收藏:Windows消息机制
百度百科介绍的windows消息机制也不错:http://baike.baidu.com/view/672379.htm Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视 ...
随机推荐
- AndroidStudio项目提交(更新)到github最详细步骤
在使用studio开发的项目过程中有时候我们想将项目发布到github上,以前都是用一种比较麻烦的方式(cmd)进行提交,最近发现studio其实是自带这种功能的,终于可以摆脱命令行了. 因为自己也没 ...
- 关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手
关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手 本人菜鸟一枚,最近公司有需求要用到富文本编辑器,我选择的是百度的ueditor富文本编辑器,闲话不多说,进入正 ...
- 简易远程消息交换协议SRMP
一.SRMP目标定位 经过十多年实战经验积累以及多方共同讨论,新生命团队(https://github.com/newlifex)制订了一种简单而又具有较好扩展性的RPC(Remote Procedu ...
- .Net Core 中间件之主机地址过滤(HostFiltering)源码解析
一.介绍 主机地址过滤中间件相当于一个白名单,标记哪些主机地址能访问接口. 二.使用 新建WebAPI项目,修改Startup中的代码段如下所示.下面表示允许主机名为“localhost”的主机访问( ...
- L1与L2损失函数和正则化的区别
本文翻译自文章:Differences between L1 and L2 as Loss Function and Regularization,如有翻译不当之处,欢迎拍砖,谢谢~ 在机器学习实 ...
- 用Vue.js搭建一个小说阅读网站
目录 1.简介 2.如何使用vue.js 3.部署api服务器 4.vue.js路由配置 5.实现页面加载数据 6.测试vue项目 7.在正式环境部署 8.Vue前端代码下载 1.简介 这是一个使用v ...
- 菜鸟入门【ASP.NET Core】14:MVC开发:UI、 EF + Identity实现、注册实现、登陆实现
前言 之前我们进行了MVC的web页面的Cookie-based认证实现,接下来的开发我们要基于之前的MvcCookieAuthSample项目做修改. MvcCookieAuthSample项目地址 ...
- confidence interval
95%置信区间.置信区间的两端被称为置信极限.对一个给定情形的估计来说,置信水平越高,所对应的置信区间就会越大. 对置信区间的计算通常要求对估计过程的假设(因此属于参数统计),比如说假设估计的误差是成 ...
- nodeJs express mongodb 建站(linux 版)
一.环境安装 1.安装node wget http://nodejs.org/dist/v0.12.2/node-v0.12.2-linux-x64.tar.gz //下载tar xvf node-v ...
- K8S 通过 yaml 文件创建资源
创建 pod cd ~ vi pod-demo.yaml # 内容如下 apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: def ...