Skip to content

4、存储管理

页式存储

正常文件都放在外层(辅存中),CPU 并非直接调用,而是把外存数据调入内存,再进行操作。

有很多本书(指代程序),想把它们放到一个有很多抽屉的图书馆(计算机的内存里)

如果不使用页式存储,你可能会想把每本书都完整地放到一个抽屉里。但问题是,有些书很大,可能找不到足够大的空抽屉来放下它们。而且,如果一个抽屉里只放了一本小书,那剩下的空间就浪费了。这就像内存里可能会有很多不连续的小块空闲空间,但任何一个程序都找不到足够连续的空间来运行。

通俗理解

  • 把每本书都撕成固定大小的页(程序被分成固定大小的块,叫做“页”)
  • 图书馆里每个抽屉都是固定大小的(内存被分成固定大小的块,叫“页框”或者“页帧”)
  • 然后就可以把书的每一页放到任何一个空的抽屉里,不需要连续的抽屉

好处

  • 更容易找到空位:所有“书页”和“抽屉”大小都一样,所以更容易找到空的“抽屉”来放“书页”,即使内存中有很多不连续的小块空闲空间,也能被利用起来,解决了找不到足够大连续空间的问题
  • 内存利用率更高:不会因为一个大程序而浪费很多小块的空闲空间

坏处

  • 需要记住每本书的每一页放在哪个抽屉里(操作系统需要维护一个“页表”,记录程序的每一页在内存中的位置)
  • 可能有“零头”:有些书的页数可能不是正好是抽屉大小的整数倍,最后一本书可能会剩下一些不满一页的内容,但仍然会占用一个完整的抽屉,叫做“页内碎片”

地址相关

  • 高级程序语言使用逻辑地址
  • 运行状态,内存中使用物理地址
  • 逻辑地址 = 页号 + 页内地址(偏移量)
  • 物理地址 = 页帧号 + 页内地址(偏移量)

页面淘汰

先淘汰访问位为 0 的,再淘汰修改位为 0 的

段式存储

通俗理解

  • 你的程序(书)被分成几个逻辑上独立的“段”(chapters)。 比如,一本书可能有“目录”段、“第一章”段、“第二章”段、“附录”段等等。每个段的长度可以是不同的,它们代表了程序中不同的功能模块或数据区域。
  • 图书馆里的抽屉(内存)现在大小不再固定了。 每个抽屉的大小可以根据你需要存放的“段”的大小来决定。
  • 当你想要把程序放到内存里时,操作系统会为每个“段”找到一个足够大的连续的空闲“抽屉”来存放。 “目录”段可能会放在一个比较小的抽屉里,“第一章”段可能会放在一个大一点的抽屉里。

好处

  • 逻辑结构清晰: 段式存储更好地保留了程序的逻辑结构。每个段都代表了程序中一个完整的逻辑单元,这有助于程序的组织和理解。
  • 易于保护和共享: 由于每个段都是一个独立的内存区域,操作系统可以针对不同的段设置不同的保护级别(例如,只读、可执行)。不同的程序也可以共享某些特定的段(例如,共享的库函数)。
  • 没有页内碎片: 因为每个段的大小是根据实际需要分配的,所以不会出现像页式存储那样,一个页面只用了很小一部分而浪费剩余空间的情况(页内碎片)。

坏处

  • 容易产生“外碎片”: 就像我们一开始不用页式存储时遇到的问题一样,经过一段时间的程序加载和卸载,内存中可能会出现很多不连续的小块空闲空间。虽然每个小块本身可能足够大,但它们加起来可能不够存放一个较大的“段”。这叫做“外碎片”。为了解决外碎片问题,可能需要进行“内存整理”(就像把图书馆里所有书挪动一下,把空抽屉都集中到一起),但这会消耗额外的系统资源。
  • 需要记住每个段放在哪个抽屉的哪个位置以及它有多大(操作系统需要维护一个“段表”,记录每个段在内存中的起始地址和长度)。 这就像图书馆需要一个更详细的索引卡片,告诉你每个章节放在哪个抽屉的哪个位置,以及这个章节有多厚。

段页式存储

是段式和页式的结合 先分段再分页

使用段页表进行管理

KESHAOYE-知识星球 V20250523200726