程序员的自我修养---3.内存分配与管理

资料下载:

链接:https://pan.baidu.com/s/1FUmks6gsNBW10EqCJ-BRFQ 

复制这段内容后打开百度网盘手机App,操作更方便哦

 1.如何将计算机上有限的物理内存分配给多个程序使用?

      假设我们的计算机有 128 MB 内存 , 程序 A 运行需耍 10 MB , 程序 B 需要 100 MB , 程序 C 需要 20 MB 。 如果我们需要间时运行程序 A 和 B , 那么比较直接的做法是将内存的前10 MB分配给程序 A , 10 MB~110 MB分配给 B 。 这样就能够实现 A 和 B 两个程序同时运行 . 但是这种简单的内存分配策略问题很多 。
• 地址空间不隔离

所有程序都直接访问物理地址 ,程序所使用的内存空间不是相互隔离的 。 恶意的程序可以很容易改写其他程序的内存数据 , 以达到破坏的目的 : 有些非恶意的 、 但是有臭虫的程序可能不小心修改了其他程序的数据 , 就会使其他程序也崩溃 , 这对于需要安全稳定的计算环境的用户来说是不能容忍的 。 用户希望他在使用计算机的时候 , 其中一个任务失败了 , 至少不会影响其他任务 。
• 内存使用效率低

由丁没有有效的内存管理机制 , 通常需要一个程序执行时 , 监控程序就将整个程序装入内存中然后开始执行 。 如果我们忽然需要运行程序 C , 那么这时内存空间其实己经不够了 , 这时候我们可以用的一个办法是将其他程序的数据皙时写到磁盘里面 , 等到需要用到的时候再读回来 。 由亍程序所需要的空间是连续的 , 那么这个例子里面.如果我们将程序 A 换出到磁盘所释放的内存空间是不够的 , 所以只能将 B 换出到磁盘 , 然后将 C 读入到内存开始运行 。 可以看到整个过程中有大最的数据在换入换出 , 导致效率十分低下 。
• 程序运行的地址不确定
       因为程序每次需要装入运行时 ,我们都需要给它从内存中分配一块足够大的空闲区域 , 这个空闲区域的位置是不确定的 。 这给程序的编写造成了一定的麻烦 , 因为程序在编写时 , 它访问数椐和指令跳转时的目标地址很多都是固定的 , 这涉及程序的重定位问题 . 我们在第 2 部分和第 3 部分还会洋细探讨重定位的问题 。
      解决这几个问题的思路就是使用我们前文提到过的法宝 : 增加中间层 , 即使用一种间接的地址访问方法 。 整个想法是这样的 , 我们把程序给出的地址看作是一种虚拟地址 ( Virtual Address ) . 然后通过某 些映射的方法 , 将这个虚拟地址转换成实际的物理地址 。 这样 , 只耍我们能够妥善地控制这个虚拟地址到物理地址的映射过程 , 就可以保证任意一个程序所能够访问的物理内存区域跟另外一个程序相互不重叠 . 以达到地址空间隔离的效果 。

      虚拟地址空间是指虚拟的 、 人们想象出来的地址空间 , 其实它并不存在 , 每个进程都有自匕独立的虚拟空间 , 而且每个进程只能访问自己的地址空间 , 这样就有效地做到了进程的隔离 。

2.分段 ( Segmentation )
开始人们使用的是一种叫做分段 ( Segmentation ) 的方法 , 基木思路是把一段与程序所需要的内存空间大小的虚拟空间映射到某个地址空间 。 比如程序 A 需要 10 MB 内存 ,那么我们假设有一个地址从 0 x 00000000 到 OxOOAOOOOO 的 10 MB 人小的一个假象的空间 ,也就是虚拟空间 , 然后我们从实际的物理内存中分配一个相同大小的物理地址 , 假设是物理地址 0 x 00100000 开始到 OxOOBOOOOO 结束的一块空间 。 然后我们把这两块相间人小的地址空间一一映射 , 即虚拟空间中的每个字节相对应于物理空间中的每个字节 。 这个映射过程由软件来设置 , 比如操作系统来设置这个映射函数 , 实际的地址转换由硬件完成 。 比如当程序 A 中访问地址 0 x 00001000 时 , CPU 会将这个地址转换成实际的物理地址0 x 0010 1 000 。 那么比如程序 A 和程序 B 在运行时 , 它们的虚拟空间和物理空间映射关系可能如图 所示 。

         分段的方法基本解决了上面提到的 3 个 N 题中的第一个和第三个 。 首先它做到了地址离离 , 因为程序 A 和程序 B 被映射到了两块不同的物理空间区域 , 它们之间没有任何重叠 ,如果程序 A 访问虚拟空间的地址超出了 OxOOAOOOOO 这个范围 , 那么硬件就会判断这是一个非法的访问 , 拒绝这个地址请求 , 并将这个请求报告给操作系统或监控程序 , 由它来决定如何处理 。 再者 , 对于每个程序来说 , 无论它们被分配到物理地址的哪一个区域 , 对于程序来说都是透明的 , 它们不需要关心物理地址的变化 , 它们只需要按照从地址 0 x 00000000 到OxOOAOOOOO 来编写程序 、 放置变量 , 所以程序不再需要重定位 。

       但是分段的这种方法还是没有解决我们的第二个问题 , 即内存使用效率的问题 。 分段对内存区域的映射还是按照程序为单位 , 如果内存不足 , 被换入换出到磁盘的都是整个程序 ,这样势必会造成大量的磁盘访 问操作 , 从而严重影响速度 , 这种方法还是显得粗糙 , 粒度比较大 。 事实上 , 根据程序的局部性原理 . 当一个程序在运行时 , 在某个时间段内 , 它只是频
繁地用到了一小部分数据 , 也就是说 , 程序的很多数据其实在一个时间段内都是不会被用到的 。 人们很自然地想到了更小粒度的内存分割和映射的方法 , 使得程序的局部性原理得到充分的利用 . 大大提卨了内存的使用率 。 这种方法就是分页 ( Paging ) 。

3.分页 ( Paging )
     分页的基本方法是把地址空间人为地等分成阀定大小的页 , 每一页的大小由硬件决定 ,或硬件支持多种大小的页 , 由操作系统选择决定页的大小 。 比如intel Pentium 系列处理器支持4 KB 或 4 MB 的页大小 , 那么操作系统 可以选择每页大小为 4 KB , 也可以选择每页大小为 4 MB ,但是在同一时刻只能选择一种大小 , 所以对整个系统来说 , 页就是固定大小的 。 目前几乎所有的 PC 上的操作系统都使用 4 KB 大小的页 。 我们使用的 PC 机是 32 位的虚拟地址空间 , 也就是 4 GB , 那么按 4 KB 每页分的话 , 总共有 1048576 个页 。 物理空间也是同样的分法 。下由我们来看一个简单的例子 . 如图 1 -6所示 , 每个虚拟空间有 8 页 , 每页大小为 1 KB ,那么虚拟地址空间就是 8 KB 。 我们假设该计算机有 13 条地址线 , 即拥有 2 的 13次方 的物理寻址能力 , 那么理论上物理空间可以多达 8 KB 。 但是出于种种原因 , 购买内存的资金不够 , 只买得起 6 KB 的内存 , 所以物理空间其实典 £ 有效的只是前 6 KB 。

     那么 , 当我们把进程的虚拟地址空间按页分割 , 把常用的数据和代码页装载到内存屮 ,把不常用的代码和数据保存在磁盘里 , 肖需要用到的时候再把它从磁盘里取出来即可 。 以图1 - 6 为例 , 我们假设有两个进程 Process 1和 Process2 , 它们进程中的部分虚拟页面被映射到了物理页面 , 比如 VPO 、 VP 1 和 VP 7 映射到 PPO 、 PP 2 和 PP 3 ; 而有部分页面却在磁盘中 ,比如 VP 2 和 VP 3 位于磁盘的 DP 0 和 DPI 中 : 另外还有一些页面如 VP 4 、 VP 5 和 VP 6 可能尚未被用到或访问到 , 它们皙时处于未使用的状态 。 在这里 , 我们把虚拟空间的页就叫虚拟页 ( VP , Virtual Page ) , 把物理内存中的页叫做物理页 ( PP , Physical Page ) , 把磁盘中的页叫做磁盘页 ( DP , Disk Page ) 。 图中的线表示映射关系 , 我们可以看到虚拟空间的有些页被映射到同一个物理页 , 这样就可以实现内存共享 。

     图 1- 6中 Processl 的 VP 2 和 VP 3 不在内存中 , 但是当进程需要用到这两个页的时候 ,硬件会捕获到这个消息 , 就是所谓的页错误 ( Page Fault ) , 然后操作系统接管进程 ,负责将 VP 2 和 VP 3 从磁盘中读出来并且装入内存 , 然后将内存中的这两个页与 VP 2 和 VP 3 之间建立映射关系 。 以页为单位来存取和交换这些数据非常方便 , 硬件本身就支持这种以页为单位的操作方式 。

       保护也是页映射的目的之,简单地说就是每个页可以设置权限厲性 , 谁可以修改 , 谁可以访问等 , 而只有操作系统有权限修改这些属性 , 那么操作系统就可以做到保护自己和保护进程 。 对于保护 , 我们这里只是简笮介绍 , 详细的介绍和为什么耍保护我们将会在本书的第 2 部分再介绍 。
      虚拟存储的实现需要依靠硬件的支持 , 对子不间的 CPU 来说是不同的 。 但是几乎所有的硬件都采用一个叫 MMU
( Memory Management Unit ) 的部件来进行页映射 . 如图丨 - 7所示 。

 在页映射模式下 ,CPU 发出的是Virtual Address , 即我们的程序看到的是虚拟地址 。 经过 MMU 转换以后就变成了 Physical Address 。 一般 MMU 都集成在 CPU 内部了 , 不会以独立的部件存在 。

发布了81 篇原创文章 · 获赞 17 · 访问量 6026

猜你喜欢

转载自blog.csdn.net/hopegrace/article/details/103865840