一、实模式下内存分配机制

在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个步骤:

  1. 预定(reserve):告诉系统我们要从虚拟地址空间预定哪一块区域,系统为我们保留这一块区域。预定的局域的起始地址和大小遵循上面介绍的分配粒度页面大小的要求。因为预定的只是虚拟地址空间,不占用任何其他物理存储器,所以没有形成实质的开销。
  2. 调拨(commit):预定的区域还不能使用,我们还需要为预定的区域从页交换文件调拨存储器,调拨之后我们才能使用该区域。
    至于为什么要从页交换文件中调拨存储器? 页交换文件如何与物理内存之间交互?下一篇文章《Windows内存体系(2) – 虚拟内存》会介绍。

Windows内存体系(1) -- 虚拟地址空间相关推荐

  1. linux和windows的进程的虚拟地址空间

    昨晚看到了深夜,终于对进程的虚拟地址空间有了个大致的了解,很激动,也很欣慰.回头想来,一个程序员,真的应该知道这些知识,否则还真不太称职. 首先告诉大家,我后面提到的这些知识在<windows核 ...

  2. Windows内存体系(2) -- 页交换文件

    一.页交换文件 虚拟地址空间只是操作系统为进程"虚拟"出来的一块地址区域,并不代表任何实际的空间.而"页交换文件"却对应了实际的空间,这个空间一般是磁盘上名为& ...

  3. 第13章Windows内存体系架构下

    1.物理存储与页文件 在以前的操作系统中,物理存储被认为是你机器上拥有RAM的数量.换句话说,如果你机器上有16MB的RAM,你能够加载和运行的程序最多使用16MB的RAM.目前的操作系统已经使硬盘空 ...

  4. Windows内存体系(6) -- 彻底理解内存对齐

    一.内存为什么要对齐 虽然所有的变量都是保存在特定地址的内存中,但最好还是按照内存对齐的要求来存储.这主要出于两个方面的原因考虑: 平台原因: 不是所有的硬件平台(特别是嵌入式系统中使用的低端处理器) ...

  5. 【读书笔记】【程序员的自我修养 -- 链接、装载与库(二)】进程虚拟地址空间、装载与动态链接、GOT、全局符号表、共享库的组织、DLL、C++与动态链接

    文章目录 前言 介绍 可执行文件的装载与进程 进程虚拟地址空间 装载方式 操作系统对可执行文件的装载 进程虚存空间分布 ELF文件的链接视图和执行视图 堆和栈 Linux 内核装载ELF & ...

  6. 【Linux 内核】进程管理 ( 进程与操作系统 | 进程与程序 | 进程与线程 | 虚拟地址空间 )

    文章目录 一.进程与操作系统 二.进程与程序 三.进程与线程 四.虚拟地址空间 一.进程与操作系统 操作系统与硬件的关系 : 操作系统 使用 硬件 提供的资源 , 如 CPU , 内存 , 磁盘 , ...

  7. 【Linux 内核 内存管理】内存映射原理 ① ( 物理地址空间 | 外围设备寄存器 | 外围设备寄存器的物理地址 映射到 虚拟地址空间 )

    文章目录 一.物理地址空间 二.外围设备寄存器 三.外围设备寄存器物理地址 映射到 虚拟地址空间 一.物理地址空间 " 物理地址空间 " 是 CPU 处理器 在 " 总线 ...

  8. Windows把内存变成快速虚拟硬盘

    笔记本电脑安装了8G内存,却装了个Win7 32位系统,结果只能识别2946MB内存,还有5GB多内存白白浪费了,那个闹心啊,别提多不爽,听说能把内存虚拟成硬盘使用,用它缓存系统临时文件,以及缓存网页 ...

  9. 【Linux 内核 内存管理】虚拟地址空间布局架构 ① ( 虚拟地址空间布局架构 | 用户虚拟地址空间划分 )

    文章目录 一.虚拟地址空间布局架构 二.用户虚拟地址空间划分 一.虚拟地址空间布局架构 在 646464 位的 Linux 操作系统中 , " ARM64 架构 " 并 不支持 6 ...

最新文章

  1. Mybatis---总结
  2. iptraf 打不开
  3. php如何获取常量的值,php – 如何获取常量的名称?
  4. 2013\National _C_C++_A\2.骰子迷题
  5. mediawiki mysql_MediaWiki
  6. 【独家】孙茂松:从机器翻译到古诗生成
  7. USACO Dual Palindrome
  8. 基础总结篇之九:Intent应用详解
  9. 怎么样把c语言和单片机融合,求助怎么把两个单片机c语言程序结合在一起?大一期末实验...
  10. 前端开发工程师应该关注什么?
  11. linux shell cut -d ‘:‘ -f1,3
  12. java里面default是什么意思_default_default是什么意思???
  13. Vplayer:一下团队打造的Android万能播放器
  14. ARM Cortex M3处理器概述
  15. 希尔伯特:无穷小是理想元素
  16. 《机器学习实战》(十)-- Apriori
  17. ubuntu安装微信,解决网页版微信不能登陆问题
  18. 宝藏下载神器,python一键下载B站视频
  19. ARMv7 与 ARMv8的区别
  20. Android 7再带壁纸,Android7 添加壁纸系统或替换系统壁纸

热门文章

  1. 行业追踪,2023-07-04,受特斯拉中报影响,汽车零部件放量强势拉升,不调整
  2. 新大陆物联网-Android实现网关功能-连接云平台并上传传感器数据-获取执行器指令并执行-Android网关开发-通信-数据上传云平台-JAVA原理讲解-免费云平台使用-竞赛2022国赛真题
  3. HUAWEI 机试题:充分发挥GPU算力
  4. 转贴-3种方法可以让你更好地了解你自己。
  5. stylus的使用和基础知识
  6. CountdownLatch(门闩)
  7. 天津理工大学信息论与编码实验(2)
  8. android ndk 文件管理,Android NDK 入门与实践
  9. 解决Android中WebView跳转到浏览器的问题
  10. 添加剂计算机,老生常谈添加剂