Windows内存体系(1) -- 虚拟地址空间
一、实模式下内存分配机制
在8086或者80186以前,要运行一个程序,操作系统会把这些程序全都装入内存,程序都是直接运行在物理内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。
例如某台计算机总的内存大小是128M
,现在同时运行两个程序 A和B ,A需占用内存10M
, B需占用内存110M
。计算机在给程序分配内存时会采取这样的方法:先将内存中的前10M
分配给程序 A ,接着再从内存中剩余的118M
中划分出 110M
分配给程序B 。这种分配方法虽然可以保证程序A和程序B都能运行,但是这种简单的内存分配策略会导致很多问题:
问题 1 :进程地址空间不隔离。由于程序都是直接访问物理内存,所以恶意程序可以随意修改别的进程的内存数据,以达到破坏的目的。有些非恶意的,但是有 bug 的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。这种情况对用户来说是无法容忍的,因为用户希望使用计算机的时候,其中一个任务失败了,至少不能影响其它的任务。
问题 2 :内存使用效率低。在 A 和 B 都运行的情况下,如果用户又运行了程序 C ,而程序 C 需要 20M 大小的内存才能运行,而此时系统只剩下 8M 的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来供程序 C 使用,然后再将程序 C 的数据全部装入内存中运行。可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。
问题 3 :程序运行的地址不确定。当内存中的剩余空间可以满足程序 C 的要求后,操作系统会在剩余空间中随机分配一段连续的 20M 大小的空间给程序 C 使用,因为是随机分配的,所以程序运行的地址是不确定的。
二、虚拟地址空间介绍
操作系统让每个进程都有自己的虚拟地址空间(Virtual Address Space
,简称VAS
)。以32位进程为例,每个进程都有0x00000000 ~ 0xFFFFFFFF
(4GB)的虚拟地址空间,所以每个进程都可能分配到0x123456
地址的内存,但这个地址不能在进程间相互访问。
因为这些都是“虚拟”的地址空间,这些“地址”都不能直接使用,CPU在寻址的时候虽然是按照虚拟地址来寻址的,但是还要通过MMU
(内存管理单元)来将虚拟地址转换为物理存储器(如内存等)上的物理地址:
从图上可以看出,进程A和B虽然都有地址0x123456
,但它们分别对应的物理地址不一样。
三、虚拟地址空间分区
进程的虚拟地址空间虽然很大,但是它被划分成了很多分区,供Ring3层应用程序使用的用户模式分区并不大(一半不到),如图:
3.1 空指针赋值分区
这一分区的进程地址空间的范围为:[0x00000000
, 0x0000FFFF
],总大小为64K
,保留该分区的目的是为了帮助应用程序员捕获对空指针的赋值。如malloc
分配内存失败,就会返回NULL
。
如果进程中的线程试图访问该分区内的内存地址,就会引发访问违规。
3.2 用户模式分区
在Windows中,所有的exe和动态链接库都载入到这一区域。系统同时会把该进程可以访问的所有内存映射文件(后面会介绍)映射到这一分区。
进程无法通过指针来读取、写入、访问其他进程的这一分区,因此一个应用程序破坏另一个应用程序的可能性就非常小了,从而使整个系统更加坚固。
3.3 内核模式分区
内核模式分区是操作系统代码的驻地。与线程调度、内存管理、文件系统支持、网络支持以及设备驱动程序相关的代码都会载入到这一分区。该分区内的代码和数据被完全的保护起来了,如果一个应用程序试图读取或写入位于这一分区的内存地址,会引发访问违规。
驻留在这一分区内的代码为所有进程共有。
四、虚拟地址空间的使用
虚拟地址空间的使用涉及到3个概念:页面大小
、分配粒度
、预定和调拨
。
4.1 页面大小
虚拟地址空间被分成以“页面”
为单位,因为硬件内存管理单元是以页面
为粒度将虚拟地址转译成物理地址的。页面
的大小根据不同的CPU不而有所不同。x86和x64系统使用的页面
大小都是4KB
,而IA-64系统使用的页面
大小是8KB
。
IA-64操作系统只能在INTEL安腾系列处理器及AMD部分服务器处理器运行,所以主流市场并不常见
当应用程序在虚拟地址空间分配空间时,系统需要确保分配区域的大小正好是系统页面
大小的整数倍。
4.2 分配粒度
当应用程序在从虚拟地址空间分配空间时,系统会确保所有分配区域的起始地址都是分配粒度
的整数倍。分配粒度
的会根据不同的CPU平台而有所不同,但目前所有的CPU平台的分配粒度都是使用64KB
。也就是说,分配的起始地址 = 64 * N
。
通过Windows的GetSystemInfo
函数也可以获得此分配粒度值。
上面所说的
分配粒度
和页面大小
的限制,只是针对于“应用程序”
,系统内核自己不存在这样的限制。
4.3 预定和调拨
虚拟地址空间的使用分为2个步骤:
- 预定(reserve):告诉系统我们要从虚拟地址空间
预定
哪一块区域,系统为我们保留这一块区域。预定的局域的起始地址和大小遵循上面介绍的分配粒度
和页面大小
的要求。因为预定的只是虚拟地址空间,不占用任何其他物理存储器,所以没有形成实质的开销。 - 调拨(commit):预定的区域还不能使用,我们还需要为
预定
的区域从页交换文件
中调拨
存储器,调拨
之后我们才能使用该区域。
至于为什么要从页交换文件
中调拨存储器?页交换文件
如何与物理内存之间交互?下一篇文章《Windows内存体系(2) – 虚拟内存》会介绍。
Windows内存体系(1) -- 虚拟地址空间相关推荐
- linux和windows的进程的虚拟地址空间
昨晚看到了深夜,终于对进程的虚拟地址空间有了个大致的了解,很激动,也很欣慰.回头想来,一个程序员,真的应该知道这些知识,否则还真不太称职. 首先告诉大家,我后面提到的这些知识在<windows核 ...
- Windows内存体系(2) -- 页交换文件
一.页交换文件 虚拟地址空间只是操作系统为进程"虚拟"出来的一块地址区域,并不代表任何实际的空间.而"页交换文件"却对应了实际的空间,这个空间一般是磁盘上名为& ...
- 第13章Windows内存体系架构下
1.物理存储与页文件 在以前的操作系统中,物理存储被认为是你机器上拥有RAM的数量.换句话说,如果你机器上有16MB的RAM,你能够加载和运行的程序最多使用16MB的RAM.目前的操作系统已经使硬盘空 ...
- Windows内存体系(6) -- 彻底理解内存对齐
一.内存为什么要对齐 虽然所有的变量都是保存在特定地址的内存中,但最好还是按照内存对齐的要求来存储.这主要出于两个方面的原因考虑: 平台原因: 不是所有的硬件平台(特别是嵌入式系统中使用的低端处理器) ...
- 【读书笔记】【程序员的自我修养 -- 链接、装载与库(二)】进程虚拟地址空间、装载与动态链接、GOT、全局符号表、共享库的组织、DLL、C++与动态链接
文章目录 前言 介绍 可执行文件的装载与进程 进程虚拟地址空间 装载方式 操作系统对可执行文件的装载 进程虚存空间分布 ELF文件的链接视图和执行视图 堆和栈 Linux 内核装载ELF & ...
- 【Linux 内核】进程管理 ( 进程与操作系统 | 进程与程序 | 进程与线程 | 虚拟地址空间 )
文章目录 一.进程与操作系统 二.进程与程序 三.进程与线程 四.虚拟地址空间 一.进程与操作系统 操作系统与硬件的关系 : 操作系统 使用 硬件 提供的资源 , 如 CPU , 内存 , 磁盘 , ...
- 【Linux 内核 内存管理】内存映射原理 ① ( 物理地址空间 | 外围设备寄存器 | 外围设备寄存器的物理地址 映射到 虚拟地址空间 )
文章目录 一.物理地址空间 二.外围设备寄存器 三.外围设备寄存器物理地址 映射到 虚拟地址空间 一.物理地址空间 " 物理地址空间 " 是 CPU 处理器 在 " 总线 ...
- Windows把内存变成快速虚拟硬盘
笔记本电脑安装了8G内存,却装了个Win7 32位系统,结果只能识别2946MB内存,还有5GB多内存白白浪费了,那个闹心啊,别提多不爽,听说能把内存虚拟成硬盘使用,用它缓存系统临时文件,以及缓存网页 ...
- 【Linux 内核 内存管理】虚拟地址空间布局架构 ① ( 虚拟地址空间布局架构 | 用户虚拟地址空间划分 )
文章目录 一.虚拟地址空间布局架构 二.用户虚拟地址空间划分 一.虚拟地址空间布局架构 在 646464 位的 Linux 操作系统中 , " ARM64 架构 " 并 不支持 6 ...
最新文章
- 无意中发现一位大佬的算法刷题pdf笔记
- [转载] 七龙珠第一部——第032话 飞天要塞
- ASP.NET中数据缓存
- linux最常用的目录表示,Linux磁盘分区的命名方式和常用目录?【每日一个知识点第84期-Linux】...
- 论文浅尝 - ICML2020 | 对比图神经网络解释器
- 距离矢量算法matlab实现,一种基于最小费用距离模型的城市生态网络构建方法与流程...
- Android View添加 Listener 小技巧示例
- fatal error: stropts.h: 没有那个文件或目录
- 计算机管理员账户权限不足,用户权限不足,请使用管理员权限。怎么办啊?求高手帮忙!谢了。...
- 环境试验的认识和环境可靠性测试
- 关于Keil 5 下载及安装教程
- lvds输入悬空_LVDS技术原理及详细介绍
- JSON简介与解析方法(超级详细)
- 7、Java基础——从控制台输入:Scanner类的的用法、数据类型转换、字符型的运算、print与println的区别、Java中的转义字符
- 如何利用手机访问电脑本地的localhost?
- 30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)
- 入行大数据需要学习哪些编程语言
- android app 仿小米全面屏手势返回UI样式
- 转载:word2019写公式序号
- 淘宝网首页登录失败原因分析及解决…
热门文章
- 杂项 杂项 杂项 杂项 杂项
- 腾讯云cos预签名上传文件
- iMX6ULL烧录提示 wait for /dev/mmcblk0
- Python爬虫百度新闻标题,并且做简单的数据分析!挺简单的
- 计算机绘图实验一报告,计算机绘图实验的报告.doc
- python爬虫:解决爬取文字时写入出现的NBSP(空格)现象
- The baby-bust economy “婴儿荒”经济 | 经济学人20230603版社论双语精翻
- 转贴-3种方法可以让你更好地了解你自己。
- 军校空军士官计算机专业,军校分不够,没关系!18所士官学校报考名单来袭!...
- 毕昇配置pytorch