内存管理——分页分段
虚拟内存
-
问题:单片机的CPU直接操作内存的【物理地址】,在这种情况下,内存中无法同时运行两个程序。假设程序A在200写入一个新值,就会擦掉程序B存放在相同位置上的所有内容。操作系统如何解决这个问题?
-
解:引入虚拟内存。即让操作系统为每个进程分配独立的一套【虚拟地址】,如果程序访问虚拟地址时,由操作系统转换成不同的物理地址,这样不同程序运行,写入的是不同的物理地址,冲突解决了。
-
问题:操作系统如何管理虚拟地址与物理地址之间的关系?
-
解:主要有两种方式,分别是【内存分段】和【内存分页】。
-
问题:虚拟地址和逻辑地址???
-
解: 来自知乎的解答
内存分段
-
程序是由若干个逻辑分段组成的,可由代码分段、数据分段、栈段、堆段组成。不同的段有不同的属性,所以用分段的形式把这些段分离出来
-
问题:分段机制下,虚拟地址和物理地址如何映射?
-
解:段基地址+段内偏移量=物理地址。
-
详解:分段机制下,虚拟地址由两部分组成,段选择因子和段内偏移量。
-
【段选择因子】保存在段寄存器里面。段选择因子里最重要的是【段号】,用作段表索引。【段表】里保存的是这个段的基地址、界限和特权等级等。
-
虚拟地址中的【段内偏移量】应该位于 0 和段界限之间,如果段内偏移量是合法的,就将段基地址+段内偏移量=物理内存地址。
-
问题:假设有 1G 的物理内存,用户执行了多个程序,其中:游戏占用了 512MB 内存、浏览器占用了 128MB 内存、音乐占用了 256 MB 内存。这个时候,如果我们关闭了浏览器,则空闲内存还有 1024 - 512 - 256 = 256MB。如果这个 256MB 不是连续的,被分成了两段 128 MB 内存,这就会导致没有空间再打开一个 200MB 的程序。这时候就产生了内存碎片问题。何解?
-
解:内存碎片有两种,相应的解决方式也不同。
-
外部内存碎片,也就是产生了多个不连续的小物理内存,导致新的程序无法被装载;
-
解:把音乐程序占用的那 256MB 内存写到硬盘上,然后再从硬盘上读回来到内存里。不过再读回的时候,我们不能装载回原来的位置,而是紧紧跟着那已经被占用了的 512MB 内存后面。这样就能空缺出连续的 256MB 空间,于是新的 200MB 程序就可以装载进来。
-
内部内存碎片,程序所有的内存都被装载到了物理内存,但是这个程序有部分的内存可能并不是很常使用,这也会导致内存的浪费;
-
解:不知道,文章没有写,来自****大佬的解答
-
问题:分段为什么会导致内存交换效率低的问题?何解?
-
对于多进程的系统来说,用分段的方式,内存碎片是很容易产生的,产生了内存碎片,那不得不重新 Swap 内存区域,这个过程会产生性能瓶颈。
-
因为硬盘的访问速度要比内存慢太多了,每一次内存交换,我们都需要把一大段连续的内存数据写到硬盘上。
-
所以,如果内存交换的时候,交换的是一个占内存空间很大的程序,这样整个机器都会显得卡顿。
-
解:为了解决内存分段的内存碎片和内存交换效率低的问题,就出现了【内存分页】
内存分页
-
分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,我们叫页(Page)。在 Linux 下,每一页的大小为 4KB。
-
页表实际上存储在 CPU 的内存管理单元 (MMU) 中,于是 CPU 就可以直接通过 MMU,找出要实际要访问的物理内存地址。
-
而当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入系统内核空间分配物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。
-
问题:分页是怎么解决分段的内存碎片、内存交换效率低的问题?
-
解内存碎片:由于内存空间都是预先划分好的,也就不会像分段会产生间隙非常小的内存,这正是分段会产生内存碎片的原因。而采用了分页,那么释放的内存都是以页为单位释放的,也就不会产生无法给进程使用的小内存。
-
解交换效率低:如果内存空间不够,操作系统会把其他正在运行的进程中的【最近没被使用】的内存页面给释放掉,也就是暂时写在硬盘上,称为换出(Swap Out)。一旦需要的时候,再加载进来,称为换入(Swap In)。所以,一次性写入磁盘的也只有少数的一个页或者几个页,不会花太多时间,内存交换的效率就相对比较高。
-
问题:分页机制下,虚拟地址和物理地址是如何映射的?
-
解:基地址+页内偏移=物理内存地址。 在分页机制下,虚拟地址分为两部分,页号和页内偏移。页号作为页表的索引,页表包含物理页每页所在物理内存的基地址,基地址+页内偏移=物理内存地址,见下图。
- 阅读微信公众号【小林coding 小林coding】之后的笔记,深入了解建议去看公众号