3 内存的基础知识


前言

次文章为观看王道考研课程(操作系统)的笔记
视频链接:https://www.bilibili.com/video/BV1YE411D7nH?spm_id_from=333.337.search-card.all.click

3.1内存的基础知识

3.1.1 什么是内存,有何作用

内存是用于存放数据的硬件。程序执行前 需 要 先 放 到 内 存 中 才 能 被 C P U 处 理 \color{red}需要先放到内存中才能被CPU处理 CPU

内存中也有一个一个的“小房间”,每个小房间就是个“ 存 储 单 元 \color{red}存储单元
如果计算机“ 按 字 节 编 址 \color{red}按字节编址 ”则 每 个 存 储 单 元 大 小 \color{red}每个存储单元大小 1 字 节 \color{red}1字节 1,即1B,即8个二进制位
如果 字 长 为 16 位 \color{red}字长为16位 16的计算机“ 按 字 编 址 \color{red}按字编址 ”,则 每 个 存 储 单 元 大 小 \color{red}每个存储单元大小 1 个 字 \color{red}1个字 1;每个字的大小为16个二进制位

3.1.2 进程运行的基本原理

指令的工作原理

我们写的代码要翻译成CPU能识别的指令。这些指令会告诉CPU应该去内存的哪个地址存/取数据.这个数据应该做什么样的处理。在这个例子中,指令中直接给出了变量x的实际存放地址( 物 理 地 址 \color{red}物理地址 )但实际在生成机器指令的时候并不知道该进程的数据会被放到什么位置。所以编译生成的指令中一般是使用 逻 辑 地 址 ( 相 对 地 址 ) \color{red}逻辑地址(相对地址)

逻辑地址vs物理地址

E g : Eg: Eg:编译时只需确定变量x存放的相对地址是100(也就是说相对于进程在内存中的起始地址而言的地址)。CPU想要找到×在内存中的实际存放位置,只需要用进程的起始地址+100即可。

相 对 地 址 又 称 逻 辑 地 址 , 绝 对 地 址 又 称 物 理 地 址 。 \color{red}相对地址又称逻辑地址,绝对地址又称物理地址。

从写程序到程序运行:编辑—编译—链接—装入

编译:由编译程序将用户源代码编译成若干个目标模块(编译就是把高级语言翻译为 机 器 语 言 \color{red}机器语言 )
链接:由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块
装入(装载):由装入程序将装入模块装入内存运行

三种链接方式

  1. 静态链接:在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开。
  2. 装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式。
  3. 运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。

三种装入方式

装入的三种方式(用三种不同的方法完成 逻 辑 地 址 到 物 理 地 址 的 转 换 \color{red}逻辑地址到物理地址的转换 ):

  1. 绝对装入
    在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
    绝对装入 只 适 用 于 单 道 程 序 环 境 \color{red}只适用于单道程序环境
    程序中使用的绝对地址,可在编译或汇编时给出,也可由程序员直接赋予。通常情况下都是编译或汇编时再转换为绝对地址
  2. 静态重定位
    又称 可 重 定 位 装 入 \color{red}可重定位装入 。编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当位置。装入时对地址进行“ 重 定 位 \color{red}重定位 ”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。
    静态重定位的特点是在一个作业装入内存时, 必 须 分 配 其 要 求 的 全 部 内 存 空 间 \color{red}必须分配其要求的全部内存空间 ,如果没有足够的内存,就不能装入该作业。作业一旦进入内存后, 在 运 行 期 间 就 不 能 再 移 动 \color{red}在运行期间就不能再移动 ,也不能再申请内存空间。
  3. 动态重定位
    又称 动 态 运 行 时 装 入 \color{red}动态运行时装入 。编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址, 而 是 把 地 址 转 换 推 迟 到 程 序 真 正 要 执 行 时 才 进 行 \color{red}而是把地址转换推迟到程序真正要执行时才进行 。因此装入内存后所有的地址依然是逻辑地址。这种方式需要一个 重 定 位 寄 存 器 \color{red}重定位寄存器 的支持。采用动态重定位时 允 许 程 序 在 内 存 中 发 生 移 动 \color{red}允许程序在内存中发生移动 。重定位奇存器:存放装入模块存放的 起 始 位 置 \color{red}起始位置 .并且可将程序分配到不连续的存储区中;在程序运行前只需装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。并且可将程序分配到不连续的存储区中;在程序运行前只需装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。

3.2 内存管理的概念

3.2.1 内存空间的分配与回收
  • 连续分配管理方式
  • 非连续分配管理方式

3.2.2 内存空间的扩展

3.2.3 地址转换

为了使编程更方便,程序员写程序时应该只需要关注指令、数据的逻辑地址。而 逻 辑 地 址 到 物 理 地 址 的 转 换 \color{red}逻辑地址到物理地址的转换 (这个过程称为 地 址 重 定 位 \color{red}地址重定位 )应该由操作系统负责,这样就保证了程序员写程序时不需要关注物理内存的实际情况。
三 种 装 入 方 式 { 绝 对 装 入 : 编 译 时 产 生 绝 对 地 址      单 道 程 序 阶 段 , 此 时 还 没 有 产 生 操 作 系 统 可 重 定 位 装 入 : 装 入 时 将 逻 辑 地 址 转 换 为 物 理 地 址      用 于 早 期 的 多 道 批 处 理 操 作 系 统 动 态 运 行 时 装 入 : 运 行 时 将 逻 辑 地 址 装 换 为 物 理 地 址 , 需 要 设 置 重 定 位 装 置      现 代 操 作 系 统 三种装入方式\begin{cases} 绝对装入:编译时产生绝对地址 \ \ \ \ 单道程序阶段,此时还没有产生操作系统\\ 可重定位装入:装入时将逻辑地址转换为物理地址\ \ \ \ 用于早期的多道批处理操作系统\\ 动态运行时装入:运行时将逻辑地址装换为物理地址,需要设置重定位装置\ \ \ \ 现代操作系统 \end{cases}             

3.2.4 存储保护

保证各进程在自己的内存空间内运行,不会越界访问

内存保护可采取两科方法:
方法一:在cCU中设置一对 上 、 下 限 寄 存 器 \color{red}上、下限寄存器 ,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
方法二:采用 重 定 位 寄 存 器 \color{red}重定位寄存器 (又称 基 址 寄 存 器 \color{red}基址寄存器 )和 界 地 址 寄 存 器 \color{red}界地址寄存器 (又称 限 长 寄 存 器 \color{red}限长寄存器 )进行越界检查。重定位寄存器中存放的是进程的 起 始 物 理 地 址 \color{red}起始物理地址 。界地址寄存器中存放的是进程的 最 大 逻 辑 地 址 。 \color{red}最大逻辑地址。

3.3 覆盖与交换

内 存 空 间 的 扩 充 { 覆 盖 技 术 交 换 技 术 虚 拟 存 储 技 术 ( 后 期 再 展 开 ) 内存空间的扩充\begin{cases} 覆盖技术\\ 交换技术\\ 虚拟存储技术(后期再展开) \end{cases} ()

3.2.1 覆盖技术

早期的计算机内存很小,比如IBM推出的第一台PC机最大只支持1MB大小的内存。因此经常会出现内存大小不够的情况。
后来人们引入了 覆 盖 技 术 \color{red}覆盖技术 ,用来 解 决 “ 程 序 大 小 超 过 物 理 内 存 总 和 ” 的 问 题 \color{red}解决“程序大小超过物理内存总和”的问题

**覆盖技术的思想:**将 程 序 分 为 多 个 段 \color{red}程序分为多个段 (多个模块)。常用的段常驻内存,不常用的段在需要时调入内存。

内存中分为 一 个 “ 固 定 区 ” \color{red}一个“固定区” 若 干 个 “ 覆 盖 区 ” \color{red}若干个“覆盖区”

需要常驻内存的段放在 “ 固 定 区 ” \color{red}“固定区” 中, 调 入 后 就 不 再 调 出 \color{red}调入后就不再调出 (除非运行结束)

不常用的段放在“ 覆 盖 区 \color{red}覆盖区 ”, 需 要 用 到 时 调 入 内 存 , 用 不 到 时 调 出 内 存 \color{red}需要用到时调入内存,用不到时调出内存

必 须 由 程 序 员 声 明 覆 盖 结 构 \color{red}必须由程序员声明覆盖结构 ,操作系统完成自动覆盖。 缺 点 : 对 用 户 不 透 明 \color{red}缺点:对用户不透明 :,增加了用户编程负担。覆盖技术只用于早期的操作系统中,现在已成为历史。

3.2.2 交换技术

交换(对换)技术的设计思想:内存空间紧张时,系统将内存中某些进程暂时 换 出 \color{red}换出 外存,把外存中某些已具备运行条件的进程 换 入 \color{red}换入 内存(进程在内存与磁盘间动态调度)
中 级 调 度 ( 内 存 调 度 ) \color{red}中级调度(内存调度) ,就是要决定将哪个处于挂起状态的进程重新调入内存。

  1. 具有对换功能的操作系统中,通常把磁盘空间分为 文 件 区 \color{red}文件区 对 换 区 \color{red}对换区 两部分。 文 件 区 \color{red}文件区 主要用于存放文件, 主 要 追 求 存 储 空 间 的 利 用 率 \color{red}主要追求存储空间的利用率 ,因此对文件区空间的管理 采 用 离 散 分 配 方 式 \color{red}采用离散分配方式 : 对 换 区 \color{red}对换区 空间只占磁盘空间的小部分, 被 换 出 的 进 程 数 据 就 存 放 在 对 换 区 \color{red}被换出的进程数据就存放在对换区 。由于对换的速度直接影响到系统的整体速度,因此对换区空间的管理 主 要 追 求 换 入 换 出 速 度 \color{red}主要追求换入换出速度 ,因此通常对换区采用 连 续 分 配 方 式 \color{red}连续分配方式 (学过文件管理章节后即可理解)。总之, 对 换 区 的 I / o 速 度 比 文 件 区 的 更 快 \color{red}对换区的I/o速度比文件区的更快 I/o
  2. 交换通常在许多进程运行且内存吃紧时进行,而系统负荷降低就暂停。例如:在发现许多进程运行时经常发生缺页,就说明内存紧张,此时可以换出一些进程;如果缺页率明显下降,就可以暂停换出。
  3. 可优先换出阻塞进程;可换出优先级低的进程;为了防止优先级低的进程在被调入内存后很快又被换出,有的系统还会考虑进程在内存的驻留时间…
    ( 注 意 : P C B 会 常 驻 内 存 \color{red}注意:PCB会常驻内存 :PCB,不会被换出外存)

覆 盖 与 交 换 的 区 别 { 覆 盖 时 在 同 一 个 程 序 或 进 程 中 的 交 换 是 在 不 同 进 程 ( 或 作 业 ) 之 间 的 覆盖与交换的区别\begin{cases} 覆盖时在同一个程序或进程中的\\ 交换是在不同进程(或作业)之间的 \end{cases} {()

3.3 连续分配管理方式

连 续 分 配 \color{red}连续分配 :指为用户进程分配的必须是一个 连 续 的 内 存 空 间 \color{red}连续的内存空间

3.3.1 单一连续分配

在单一连续分配方式中,内存被分为 系 统 区 \color{red}系统区 用 户 区 \color{red}用户区 。系统区通常位于内存的低地址部分,用于存放操作系统相关数据;用户区用于存放用户进程相关数据。
内存中 只 能 有 一 道 用 户 程 序 \color{red}只能有一道用户程序 ,用户程序独占整个用户区空间。
优 点 : \color{red}优点: :实现简单; 无 外 部 碎 片 \color{red}无外部碎片 ;可以采用覆盖技术扩充内存;不一定需要采取内存保护( e g eg eg:早期的PC操作系统 M S − D o S MS-DoS MSDoS)。
缺 点 \color{red}缺点 :只能用于单用户、单任务的操作系统中; 有 内 部 碎 片 \color{red}有内部碎片 ;存储器利用率极低。

分配给某进程的内存区域中,如果有些部分没有用就是“内部碎片”

3.3.2 固定分区分配

为了能在内存中装入多道程序,且这些程序之间又不会相互干扰,于是将整个 用 户 空 间 \color{red}用户空间 划分为 若 干 个 固 定 大 小 的 分 区 \color{red}若干个固定大小的分区 ,在 每 个 分 区 中 只 装 入 一 道 作 业 \color{red}每个分区中只装入一道作业 ,这样就形成了最早的、最简单的一种可运行多道程序的内存管理方式。

固定分区分配的两种方式:

  • 分区大小相等:缺乏灵活性,但是 很 适 合 用 于 用 一 台 计 算 机 控 制 多 个 相 同 对 象 的 场 合 \color{red}很适合用于用一台计算机控制多个相同对象的场合
  • 分区大小不等:增加了灵活性,可以满足不同大小的进程需求。根据常在系统中运行的作业大小情况进行划分(比如:划分多个小分区、适量中等分区、少量大分区)

操作系统需要建立一个数据结构― 分 区 说 明 表 \color{red}分区说明表 ,来实现各个分区的分配与回收。每个表项对应一个分区,通常按分区大小排列。每个表项包括对应分区的 大 小 、 起 始 地 址 、 状 态 \color{red}大小、起始地址、状态 (是否已分配)。
分 区 号 大 小 ( M B ) 起 始 地 址 ( M ) 状 态 1 2 8 未 分 配 2 2 10 未 分 配 3 4 12 已 分 配 . . . . . . . . . . . . \begin{array}{|c|c|c|c|} \hline 分区号&大小(MB)&起始地址(M)&状态\\ \hline 1&2&8&未分配\\ \hline 2&2&10&未分配\\ \hline 3&4&12&已分配\\ \hline ...&...&...&...\\ \end{array} 123...(MB)224...(M)81012......
当某用户程序要装入内存时,由操作系统内核程序根据用户程序大小检索该表,从中找到一个能满足大小的、未分配的分区,将之分配给该程序,然后修改状态为“已分配”。
优 点 : \color{red}优点: :实现简单, 无 外 部 碎 片 \color{red}无外部碎片
缺 点 : \color{red}缺点: : a.当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能; b. 会 产 生 内 部 碎 片 \color{red}会产生内部碎片 ,内存利用率低。

3.3.3 动态分区分配

动 态 分 区 分 配 \color{red}动态分区分配 又称为 可 变 分 区 分 配 \color{red}可变分区分配 。这种分配方式 不 会 预 先 划 分 内 存 分 区 \color{red}不会预先划分内存分区 ,而是在进程装入内存时 根 据 进 程 的 大 小 动 态 地 建 立 分 区 \color{red}根据进程的大小动态地建立分区 ,并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。

动态分区分配 没 有 内 部 碎 片 \color{red}没有内部碎片 ,但是 有 外 部 碎 片 \color{red}有外部碎片
内 部 碎 片 \color{red}内部碎片 ,分配给某进程的内存区域中,如果有些部分没有用上
外 部 碎 片 \color{red}外部碎片 ,是指内存中的某些空闲分区由于太小而难以利用。

如果内存中空闲空间的总和本来可以满足某进程的要求,但由于进程需要的是一整块连续的内存空间,因此这些“碎片”不能满足进程的需求。
可以通过 紧 凑 ( 拼 凑 , C o m p a c t i o n ) \color{red}紧凑(拼凑,Compaction) Compaction技术来解决外部碎片。

记录内存使用情况的方法

  • 空闲分区表:个空闲分区对应一个表项。表项含分区号分区大分区起始地址等信息

分 区 号 分 区 大 小 ( M B ) 起 始 地 址 ( M ) 状 态 1 20 8 空 闲 2 10 32 空 闲 3 4 60 空 闲 \begin{array}{|c|c|c|c|} \hline 分区号&分区大小(MB)&起始地址(M)&状态\\ \hline 1&20&8&空闲\\ \hline 2&10&32&空闲\\ \hline 3&4&60&空闲\\ \hline \end{array} 123(MB)20104(M)83260

  • 空闲分区链:每个分区的起始部分和末尾部分分别设置前向指针和后向指针。起始部分处还可记录分区大小等信息
4
10
20

当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配?

把一个新作业装入内存时,须按照一定的 动 态 分 区 分 配 算 法 \color{red}动态分区分配算法 ,从空闲分区表(或空闲分区链)中选出一个分区分配给该作业。由于分配算法算法对系统性能有很大的影响,因此人们对它进行了广泛的研究。

分区的回收

回收区和其相邻的空闲区合并

3.4 动态分区分配算法

3.4.1 首次适应算法 ( F i r s t   F i t ) (First\ Fit) (First Fit)

算 法 思 想 \color{red}算法思想 : 每次从低地址开始寻找,找到第一个满足大小的空闲分区

3.4.2 最佳适应算法 ( E e s t   F i t ) (Eest\ Fit) (Eest Fit)

算 法 思 想 \color{red}算法思想 : 空闲分区按容量递增排序,进程到来优先使用更小的可满足的空闲分区,每次分配完需要重新排序

缺 点 : 每 次 选 择 最 小 的 能 满 足 的 空 闲 分 区 , 会 留 下 大 量 很 小 的 , 难 以 利 用 的 内 存 块 , 因 此 会 产 生 大 量 外 部 碎 片 \color{red}缺点:每次选择最小的能满足的空闲分区,会留下大量很小的,难以利用的内存块,因此会产生大量外部碎片

3.4.3 最坏适应算法 ( W o r s t   F i t ) (Worst\ Fit) (Worst Fit)

又称 最 大 适 应 算 法 \color{red}最大适应算法

算 法 思 想 \color{red}算法思想 :每次优先使用最大的连续分区

缺 点 : 每 次 选 择 最 大 的 分 区 , 导 致 大 的 连 续 空 闲 分 区 被 迅 速 使 用 完 , 之 后 有 大 进 程 到 达 时 , 没 有 内 存 分 区 可 用 \color{red}缺点:每次选择最大的分区,导致大的连续空闲分区被迅速使用完,之后有大进程到达时,没有内存分区可用 使

3.4.4 临近适应算法 ( N e x t   F i t ) (Next\ Fit) (Next Fit)

算 法 思 想 : \color{red}算法思想: 先按照地址递增顺序排序,每次分配内存时从 上 次 查 找 结 束 的 位 置 开 始 \color{red}上次查找结束的位置开始 查找 空 闲 分 区 表 ( 链 ) \color{red}空闲分区表(链) (),找到第一个满足大小的空闲分区

有着最佳适应算法的优点,和最大适应算法的缺点

综合来看: 四 种 算 法 中 , 手 粗 适 应 算 法 的 效 果 最 好 \color{red} 四种算法中,手粗适应算法的效果最好
算 法 算 法 思 想 分 区 安 排 顺 序 优 点 缺 点 首 次 适 应 从 头 到 尾 找 适 合 的 空 闲 分 区 以 地 址 综 合 看 性 能 最 好 。 算 分 区 递 增 次 序 排 列 法 开 销 小 , 回 收 分 区 后 一 般 不 需 要 对 空 闲 分 区 队 列 重 新 排 序 最 佳 适 应 优 先 使 用 更 小 的 分 空 闲 分 区 以 容 量 会 有 更 多 的 大 分 区 被 会 产 生 很 多 太 小 的 、 难 以 区 , 以 保 留 跟 多 更 大 递 增 次 序 排 序 保 留 下 来 , 更 能 满 足 利 用 的 碎 片 ; 算 法 开 销 大 , 分 区 大 进 程 需 要 回 收 分 区 后 可 能 需 要 对 空 闲 分 区 队 列 重 新 排 序 最 坏 适 应 优 先 使 用 更 大 的 分 空 闲 分 区 以 容 量 可 以 减 少 难 以 利 用 的 大 分 区 容 易 2 被 用 完 , 不 利 区 , 以 防 止 产 生 太 递 减 次 序 排 列 小 碎 片 于 大 进 程 ; 算 法 开 销 大 小 的 不 可 用 的 碎 片 ( 原 因 同 上 ) 临 近 适 应 由 首 次 适 应 演 变 而 空 闲 分 区 以 地 址 不 用 每 次 都 从 低 地 址 会 使 高 地 址 的 大 分 区 也 被 来 , 每 次 从 上 次 查 递 增 次 序 排 列 的 小 分 区 开 始 检 索 。 用 完 找 结 束 位 置 开 始 查 ( 可 排 列 成 循 环 链 算 法 开 销 小 ( 原 因 同 找 表 ) 首 次 适 应 算 法 ) \begin{array}{|l|l|l|l|l|} \hline 算法&{\color{red}算法思想}&分区安排顺序&优点&缺点\\ \hline首次适应&{\color{red}从头到尾找适合的}&空闲分区以地址&综合看性能最好。算&\\&{\color{red}分区}&递增次序排列&法开销小,回收分区\\&&&后一般不需要对空闲\\&&&分区队列重新排序\\ \hline最佳适应&{\color{red}优先使用更小的分}&空闲分区以容量&会有更多的大分区被&会产生很多太小的、难以\\&{\color{red}区,以保留跟多更大}&递增次序排序&保留下来,更能满足&利用的碎片;算法开销大,\\&{\color{red}分区}&&大进程需要&回收分区后可能需要对空\\&&&&闲分区队列重新排序\\ \hline最坏适应&{\color{red}优先使用更大的分}&空闲分区以容量&可以减少难以利用的&大分区容易2被用完,不利\\&{\color{red}区,以防止产生太}&递减次序排列&小碎片&于大进程;算法开销大\\&{\color{red}小的不可用的碎片}&&&(原因同上)\\ \hline临近适应&{\color{red}由首次适应演变而}&空闲分区以地址&不用每次都从低地址&会使高地址的大分区也被\\&{\color{red}来,每次从上次查}&递增次序排列&的小分区开始检索。&用完\\&{\color{red}找结束位置开始查}&(可排列成循环链&算法开销小(原因同\\&{\color{red}找}&表)&首次适应算法)\\ \hline \end{array} 使使()()2()使

3.5 非连续分配方式

连续分配方式的缺点:

  1. 固定分区分配:缺乏灵活性,会产生大量的内部碎片,内存的利用率很低
  2. 动态分区分配:会产生很多外部碎片,虽然可以用“紧凑”技术来处理,但是“紧凑”技术的时间代价很高

3.5.1 基本分页储存管理

基本概念

  • 对于内存空间:将内存空间分为一个个 大 小 相 等 的 分 区 {\color{red}大小相等的分区} ,每个分区就是一个“ 页 框 \color{red}页框 ”,或称“ 页 帧 \color{red}页帧 ”,“ 内 存 块 \color{red}内存块 ”,“ 物 理 块 \color{red}物理块 ”。每个页框都有一个编号,即为“ 页 框 号 \color{red}页框号 ”等, 从 0 开 始 编 号 \color{red}从0开始编号 0
  • 对于用户进程:将用户进程的地址空间也分为 于 页 框 大 小 相 等 \color{red}于页框大小相等 的一个个区域,称为“ 页 \color{red}页 ”或“ 页 面 \color{red}页面 ”,每个页也有一个编号,即为“ 页 号 \color{red}页号 ”,页号也是“ 从 0 开 始 \color{red}从0开始 0
    (注意:页框不能太大,否则可能产生过大的内部碎片)
  • 操作系统以页框为单位为各个进程分配内存空间,进程的“ 页 面 \color{red}页面 ”于内存的“ 页 框 \color{red}页框 ”有“ 一 一 对 应 \color{red}一一对应 ”的关系。各页面不必连续存放。

实现地址转换

  1. 计算逻辑地址对应的“ 页 号 \color{red}页号
  2. 要知道该页号对应 页 面 在 内 存 中 的 起 始 地 址 \color{red}页面在内存中的起始地址
  3. 计算逻辑地址 在 页 面 内 的 ′ ′ 偏 移 量 ′ ′ \color{red}在页面内的''偏移量''
  4. 物 理 地 址   =   页 面 始 址   +   页 内 偏 移 量 \color{red}物理地址\ =\ 页面始址\ +\ 页内偏移量  =  + 

页表

为了能知道进程的美国页面在内存中存放的位置,操作系统要 为 每 个 进 程 建 立 一 张 页 表 \color{red}为每个进程建立一张页表

  1. 一个进程对应一张页表
  2. 进程的每一页对应一个页表面
  3. 每个 页 表 面 \color{red}页表面 由“页号”和“块号”组成
  4. 页表记录 进 程 页 面 和 实 际 存 放 的 内 存 块 之 间 的 对 应 关 系 \color{red}进程页面和实际存放的内存块之间的对应关系
  5. 每个页表项的长度是相同的, 页 号 是 ′ ′ 隐 含 ′ ′ 的 \color{red}页号是''隐含''的

基 本 地 址 变 换 机 构 { 页 表 寄 存 器 的 作 用 { 存 放 页 表 起 始 地 址 存 放 页 表 长 度 地 址 变 换 过 程 { 1. 根 据 逻 辑 地 址 算 出 页 号 、 页 内 偏 移 量 2. 页 号 的 合 法 性 检 查 ( 于 页 表 长 度 对 比 ) 3. 若 页 号 合 法 , 再 根 据 页 表 起 始 地 址 、 页 号 找 到 对 应 页 表 项 4. 根 据 页 表 项 中 记 录 的 内 存 块 号 、 页 内 偏 移 量   得 到 最 终 的 物 理 地 址 5. 访 问 物 理 内 存 对 应 的 内 存 单 元 其 它 细 节 { 页 内 偏 移 量 位 数 与 页 面 大 小 之 间 的 关 系 ( 要 能 用 其 中 一 个 条 件 推 出 另 一 个 条 件 ) 页 式 管 理 中 地 址 是 一 维 的 实 际 应 用 中 , 通 常 使 用 一 个 页 框 恰 好 能 放 入 整 数 个 页 表 项 为 了 方 便 找 到 页 表 项 , 页 表 一 般 是 放 在 连 续 的 内 存 块 中 基本地址变换机构\begin{cases} 页表寄存器的作用\begin{cases} 存放页表起始地址\\ 存放页表长度 \end{cases}\\ 地址变换过程\begin{cases} 1.根据逻辑地址算出页号、页内偏移量\\ 2.页号的合法性检查(于页表长度对比)\\ 3.若页号合法,再根据页表起始地址、页号找到对应页表项\\ 4.根据页表项中记录的内存块号、页内偏移量\ 得到最终的物理地址\\ 5.访问物理内存对应的内存单元 \end{cases}\\ 其它细节\begin{cases} 页内偏移量位数与页面大小之间的关系(要能用其中一个条件推出另一个条件)\\ 页式管理中地址是一维的\\ 实际应用中,通常使用一个页框恰好能放入整数个页表项\\ 为了方便找到页表项,页表一般是放在连续的内存块中 \end{cases} \end{cases} {1.2.()3.4. 5.访()使便

具有块表的地址变换机构

局部性原理

  • 时 间 局 部 性 \color{red}时间局部性 ::如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)
  • 空 间 局 部 性 \color{red}空间局部性 :一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的)

快表机制

基 本 地 址 变 换 机 构 \color{Red}基本地址变换机构 中,每次要访问一个逻辑地址,都需要 查 询 内 存 中 的 页 表 \color{Red}查询内存中的页表 。由于局部性原理, 可 能 连 续 很 多 次 查 到 的 都 是 同 一 个 页 表 项 \color{Red}可能连续很多次查到的都是同一个页表项

快 表 \color{Red}快表 ,又称 联 想 寄 存 器 ( T L B ) \color{Red}联想寄存器(TLB) TLB,是一种 访 问 速 度 比 内 存 快 很 多 \color{Red}访问速度比内存快很多 访的高速缓冲存储器,用来存放当前访问的若干页表项,以加速地址变换的过程。与此对应,内存中的页表常称为 慢 表 。 \color{Red}慢表。

  1. CPU给出逻辑地址,由某个硬件算得页号、页内偏移量,将页号与快表中的所有页号进行比较。
  2. 如果找到匹配的页号,说明要访问的页表项在快表中有副本,则直接从中取出该页对应的内存块号,再将内存块号与页内偏移量拼接形成物理地址,最后, 访 问 \color{Red}访问 访该物理地址对应的 内 存 单 元 \color{Red}内存单元 。因此,若 快 表 命 中 \color{Red}快表命中 ,则访问某个逻辑地址仅需 一 次 访 存 \color{Red}一次访存 访即可。
  3. 如果没有找到匹配的页号,则需要 访 问 内 存 中 的 页 表 \color{Red}访问内存中的页表 访,找到对应页表项,得到页面存放的内存块号,再将内存块号与页内偏移量拼接形成物理地址,最后, 访 问 \color{Red}访问 访该物理地址对应的 内 存 单 元 \color{Red}内存单元 。因此,若 快 表 未 命 中 \color{Red}快表未命中 ,则访问某个逻辑地址需要 两 次 访 存 \color{Red}两次访存 访
    注 意 : 在 找 到 页 表 项 后 , 应 同 时 将 其 存 入 快 表 \color{Red}注意:在找到页表项后,应同时将其存入快表 :,以便后面可能的再次访问。但若快表已满,则必须按照一定的算法对旧的页表项进行替换)
两级页表

单极页表的问题

  1. 页表必须连续存储,因此当页表很大时,需要占用很多个连续的页框
  2. 一个进程在一段时间内可能只需要访问几个特定的页面,所以页表没必要常驻内存

两级页表

  • 将长长的页表分页
  • 逻 辑 地 址 结 构 : ( 一 级 页 表 , 二 级 页 表 , 页 内 偏 移 量 ) \color{Red}逻辑地址结构:(一级页表,二级页表,页内偏移量)
  • 注 意 几 个 术 语 : 页 目 录 表 / 外 层 页 表 / 顶 级 页 表 \color{Red}注意几个术语:页目录表/外层页表/顶级页表 //

实现地址转换

  1. 按照地址结构将逻辑地址拆分成三部分
  2. P C B PCB PCB中读出页目录表始址,根据一级页号查页目录表,找到下一级页表在内存中存放位置
  3. 根据二级页号查表,找到最终想访问的内存块号
  4. 结合页内偏移量得到物理地址

注意细节

  • 多 级 页 表 中 , 各 级 页 表 的 大 小 不 能 超 过 一 个 页 面 , 若 两 级 页 表 不 够 , 可 以 分 更 多 及 \color{Red}多级页表中,各级页表的大小不能超过一个页面,若两级页表不够,可以分更多及
  • 多 级 页 表 访 问 次 数 ( 假 设 没 有 快 表 机 制 ) − − N 级 页 表 访 问 一 个 逻 辑 地 址 需 要 N + 1 次 访 存 \color{Red}多级页表访问次数(假设没有快表机制)--N 级页表访问一个逻辑地址需要N + 1 次访存 访()N访N+1访

3.5.2 基本分段储存管理

分段

  • 将地址空间按照程序自身的逻辑关系划分为若干的段,每个段从0开始编制
  • 每个段在内存中占用连续空间,但各段之间可以不相邻
  • 逻辑地址结构:(段号,段内地址)

段表

  • 记录逻辑地址到实际存储地址映射关系
  • 每个段对应一个段表项,各段表项长度相等,由段号(隐含)、 段 长 \color{Red}段长 、基址组成

地址变换

  1. 由逻辑地址得到段号,段内地址
  2. 段号与段表寄存器中的段长度比较,检查是否越界
  3. 由段表始址、段号找到对应段表项
  4. 根 据 段 表 中 记 录 的 段 长 , 检 查 段 内 地 址 是 否 越 界 \color{Red}根据段表中记录的段长,检查段内地址是否越界
  5. 由段表中的“基址+段内地址”得到最终的物理地址
  6. 访问目标单元

分段 V S VS VS 分页

  • 分页对用户不可见,分段对用户可见
  • 分页地地址空间是一维的,分段的地址空间是二维的
  • 分段更容易实现信息的共享和保护(纯代码/可重人代码可以共享)
  • 分页(单极页表)、分段访问一个逻辑地址都需要两次访存,分段存储也可以引入快表机构

3.5.3 段页式存储管理

分段、分页的优缺点
优 点 缺 点 分 页 管 理 内 存 空 间 利 用 率 高 , 不 会 产 生 外 部 不 方 便 按 照 逻 辑 模 块 实 现 信 息 的 共 享 和 保 护 碎 片 , 只 会 有 少 量 页 内 碎 片 分 段 管 理 很 方 便 按 照 逻 辑 模 块 实 现 信 息 的 共 如 果 段 长 过 大 , 为 其 分 配 很 大 的 连 续 空 间 会 很 不 方 享 和 保 护 便 。 另 外 , 段 式 管 理 会 产 生 外 部 碎 片 \begin{array}{|l|l|l|} \hline&优点&缺点\\ \hline分页管理&内存空间利用率高,{\color{Red}不会产生外部}&不方便按照逻辑模块实现信息的共享和保护\\&{\color{Red}碎片},只会有少量页内碎片\\ \hline分段管理&很方便按照逻辑模块实现信息的共&如果段长过大,为其分配很大的连续空间会很不方\\&享和保护&便。另外,段式管理{\color{Red}会产生外部碎片}\\ \hline \end{array} 便便便
分段+分页

  • 将地址空间按照程序自身的逻辑关系分为若干个段,在将各段分为大小相等的页面
  • 将内存空间分为与页面大小相等的一个个内存块,系统以块为单位为进程分配内存
  • 逻辑地址结构:(段号,页号,页内偏移量)

段表、页表

  • 每个段对应一个段表项,各段表项长度相同,由 段号(隐含)、 页 表 长 度 、 页 表 存 放 地 址 \color{Red}页表长度、页表存放地址 组成
  • 每个页对应一个页表项,各页表项长度相同,由 页号(隐含)、页面存放的内存块号 组成

地址变化

  1. 由逻辑地址得到 段号、页号、页内偏移量

  2. 段号与段表寄存器中的段长度比较,检查是否越界

  3. 由段表始址、段号找到对应段表项

  4. 根 据 段 表 中 记 录 的 页 表 长 度 , 检 查 页 号 是 否 越 界 \color{Red}根据段表中记录的页表长度,检查页号是否越界

  5. 由段表中的页表地址、页号得到查询页表,找到相应页表项

  6. 由页面存放的内存块号、页内偏移量得到最终的物理地址

  7. 访问目标单元

访问一个逻辑地址所需访问次数

  • 第一次–查段表、第二次–查页表、第三次–访问目标单元
  • 可引入快表机构,以段号和页号为关键字查询快表,即可直接找到最终的目标页面存放位置,引入快表后仅需要一次访存

3.6 虚拟内存基本概念

3.6.1 传统存储管理方式的特征、缺点

  • 一次性:作业数据必须一次全部调入内存
  • 驻留性:作业数据在整个运行期间都会常驻内存

3.6.2 局部性原理

  • 时间局部性:现在访问的指令、数据在不久后很可能被再次访问
  • 空间局部性:现在访问的内存单元周围的内存空间,很可能在不久后会被访问

3.6.3 虚拟内存的定义和特征

  • 程序不需要全部装入即可运行,运行时根据需要动态调入数据,若内存不够,还需换出一些数据
  • 特征
    1. 多次性:无需在作业运行时一次性全部装入内存,而是允许分成多次调入内存
    2. 对换性:无需在作业运行时一直常驻内存,而是允许在作业运行过程中,将作业换入换出
    3. 虚拟性:从逻辑上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量

3.6.4 如何实现虚拟技术

  • 访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存( 请 求 调 页 功 能 \color{Red}请求调页功能 )

  • 内存空间不足时,将内存中暂时用不到的信息换出到外存( 页 面 置 换 功 能 \color{Red}页面置换功能 )

  • 虚拟内存的实现

    1. 请 求 分 页 储 存 管 理 \color{Red}请求分页储存管理
    2. 请求分段储存管理
    3. 请求段页式储存管理

3.7 请求分页管理方式

3.7.1 页表机制

  • 在基本分页表的基础上增加了几个表项
  • 状态位:表示页面是否已在内存中
  • 访问字段:记录最近被访问了几次,或记录上次访问的时间,供置换算法选择出页面时参考
  • 修改位:表示页面调入内存后是否被修改过,只有修改过的页面才需要在置换时写回外存
  • 外存地址:页面在外存中存放的位置

3.7.2 缺页中断机构

  • 找到页表项后检查页面是否已存在内存,若没在内存,产生缺页中断
  • 缺页中断处理中,需要将目标页面调入内存,有必要时还要换出页面
  • 缺页中断属于内中断,属于内中断的“故障”,即可能被系统修复的异常
  • 一条指令在执行的过程中可能产生多次缺页中断

3.7.3 地址变换机构

  1. 找到页表项时需要检查页面是否存在内存中
  2. 若页面不在内存中,需要请求调页
  3. 若内存空间不够,还需要换出页面
  4. 页面调入内存后,需要修改相应页表项

3.8页面置换算法

3.8.1 最佳置换算法(OPT)

最佳置挨算法(OPT,Optimal):每次选择 淘 汰 的 页 面 \color{Red}淘汰的页面 将是 以 后 永 不 使 用 \color{Red}以后永不使用 使,或者 在 最 长 时 间 内 不 再 被 访 问 的 页 面 \color{Red}在最长时间内不再被访问的页面 访,这样可以保证最低的缺页率。
最佳置换算法可以保证最低的缺页率,但实际上,只有在进程执行的过程中才能知道接下来会访问到的足哪个页面。操作系统无法提前预判页面访问序列。因此, 最 佳 置 换 算 法 是 无 法 实 现 的 \color{Red}最佳置换算法是无法实现的

3.8.2 先进先出置换算法(FIFO)

先进先出置挨算法(FIFO):每次选择 淘 汰 的 页 面 \color{Red}淘汰的页面 最 早 进 入 内 存 的 页 面 \color{Red}最早进入内存的页面
实现方法:把调入内存的页面根据调入的先后顺序排成﹒个队列,需要换山页面时选抒队头页面即可。队列的最大长度取决于系统为进程分配了多少个内存块。
B e l a d y 异 常 常 \color{Red}Belady异常常 Belady一一当为进程分配的物理块数增大时,缺页次数不减反增的片常现象。
只 有 F I F O 算 法 会 产 生 B e l a d y 异 常 \color{Red}只有FIFO算法会产生Belady异常 FIFOBelady。另外,FIFO算法虽然 实 现 简 单 \color{Red}实现简单 ,但是该算法与进程实际运行时的规律不适应,因为先进入的页面也有可能最经常被访问。因此, 算 法 性 能 差 \color{Red}算法性能差

3.8.3 最近最久未使用置换算法(LRU)

最近最久未使用置换算法(LRU,least recently used):每次 淘 汰 的 页 面 \color{Red}淘汰的页面 最 近 最 久 未 使 用 的 页 面 \color{Red}最近最久未使用的页面 使
实现方法:赋予每个页面对应的页表项中,用 访 问 字 段 记 录 该 页 面 自 上 次 被 访 问 以 来 所 经 历 的 时 间 t \color{Red}访问字段记录该页面自上次被访问以来所经历的时间t 访访t。当需要淘汰一个页面时,选择现有页面中t值最大的,即最近最久未使用的页面。
该算法的实现需要专门的硬件支持,虽然算法 性 能 好 \color{Red}性能好 ,但是 实 现 困 难 , 开 销 大 \color{Red}实现困难,开销大

3.8.4 时钟置换算法(CLOCK)

时 钟 置 换 算 法 \color{Red}时钟置换算法 是一种性能和开销较均衡的算法,又称: C L O C K 算 法 \color{Red}CLOCK算法 CLOCK,或 最 近 未 用 算 法 ( N R U \color{Red}最近未用算法(NRU (NRU,NotRecently Used ) \color{Red}) )

简 单 的 C L O C K 算 法 \color{Red}简单的CLOCK 算法 CLOCK实现方法:为每个页面设置一个 访 问 位 \color{Red}访问位 访,再将内存中的页面都池过链接指针 链 接 成 一 个 循 环 队 列 \color{Red}链接成一个循环队列 。当某页被访问时,其访问位置为1。当需要淘汰一个页面时,只需检查页的访问位.。如果是0,就选择该页换出;如果足1,则将它置为O,暂不换出,继续检查下一个页面,若第一轮扫描巾所有页面都是1,则将这些页面的访问位依次置为O后,再进行第二轮扫描(第二轮扫描中‘定会有访问位为O的页面,因此 简 单 的 C L O C K 算 法 \color{Red}简单的CLOCK 算法 CLOCK选择一个淘汰页面 最 多 会 经 过 两 轮 扫 描 \color{Red}最多会经过两轮扫描 )

简 单 的 叮 钟 置 换 算 法 \color{Red}简单的叮钟置换算法 仅考虑到‘个页面最近是否被访问过。事实上,如果被淘汰的页面没有被修改过,就不需要执行I/o操作写回外存。 只 有 被 淘 汰 的 页 面 被 修 改 过 时 , 才 需 要 写 回 外 存 \color{Red}只有被淘汰的页面被修改过时,才需要写回外存
因此,除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。 在 其 他 条 件 都 相 同 时 , 应 优 先 淘 汰 没 有 修 改 过 的 页 面 \color{Red}在其他条件都相同时,应优先淘汰没有修改过的页面 ,避免I/0操作。这就是 改 进 型 的 时 钟 置 换 算 法 \color{Red}改进型的时钟置换算法 的思想。
修改位=0,表示页面没有被修改过;修改位=1,表示页面被修改过。
为方便讨论,用 ( 访 问 位 , 修 改 位 ) \color{Red}(访问位,修改位) (访)的形式表示各页面状态。如(1,1)表示‘个页面近期被访问过,且被修改过,

算 法 规 则 \color{Red}算法规则 :将所有可能被置换的页面排戊一个循环队列
第一轮:从当前位置开始扫描到第一个(0,0)的帧用于替换。木轮扫描不修改任何标志位
第二轮:若第轮扫描失败,则重新扫描,查找第一·个(0,1)的帧用于替换。本轮将所有扫描过的帧访问位设为o
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0,0)的帧i用于替换。本轮扫描不修改任何标志位
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0,1)的快用于替换。
由于第二轮己将所有倾的访问位设为0,因此经过第三轮、第四轮扫描一定会有一个帧被选中,因此 改 进 型 C L O C K 置 换 算 法 \color{Red}改进型CLOCK置换算法 CLOCK选择一个淘汰页面 最 多 会 进 行 四 轮 扫 描 \color{Red}最多会进行四轮扫描
算 法 思 想 优 缺 点 O P T 优 先 淘 汰 最 长 时 间 内 不 会 被 访 问 的 页 面 缺 页 率 最 小 , 性 能 最 好 ; 但 无 法 实 现 F I F O 优 先 淘 汰 最 先 进 入 内 存 的 页 面 实 现 简 单 ; 但 性 能 很 差 , 可 能 出 现 B e l a d y 异 常 L U R 优 先 淘 汰 最 近 最 久 没 访 问 的 页 面 性 能 很 好 ; 但 需 要 硬 件 支 持 , 算 法 开 销 大 C L O C K ( N U Y R ) 循 环 扫 描 各 页 面 实 现 简 单 , 算 法 开 销 小 ; 第 一 轮 淘 汰 访 问 位 = 0 的 , 并 将 扫 描 过 的 页 面 访 问 但 未 考 虑 页 面 是 否 被 修 位 改 为 1. 若 第 一 轮 没 选 中 , 则 进 行 第 二 轮 扫 描 。 改 过 。 改 进 型 C L O C K ( 改 若 用 ( 访 问 位 , 修 改 位 ) 的 形 式 表 述 , 则 算 法 开 销 较 小 , 性 能 也 进 型 N R U ) 第 一 轮 : 淘 汰 ( 0 , 0 ) 不 错 第 二 轮 : 淘 汰 ( 0 , 1 ) , 并 将 扫 描 过 的 页 面 访 问 位 都 置 为 0 第 三 轮 : 淘 汰 ( 0 , 0 ) 第 四 轮 : 淘 汰 ( 0 , 1 ) \begin{array}{|l|l|l|} \hline&算法思想&优缺点\\ \hline OPT&优先淘汰最长时间内不会被访问的页面&缺页率最小,性能最好;\\&&但无法实现\\ \hline FIFO&优先淘汰最先进入内存的页面&实现简单;但性能很差,\\&&可能出现Belady异常\\ \hline LUR&优先淘汰最近最久没访问的页面&性能很好;但需要硬件\\&&支持,算法开销大\\ \hline CLOCK(NUYR)&循环扫描各页面&实现简单,算法开销小;\\&第一轮淘汰访问位=0的,并将扫描过的页面访问&但未考虑页面是否被修\\&位改为1.若第一轮没选中,则进行第二轮扫描。&改过。\\ \hline 改进型CLOCK(改&若用(访问位,修改位)的形式表述,则&算法开销较小,性能也\\进型NRU)&第一轮:淘汰(0,0)&不错\\&第二轮:淘汰(0,1),并将扫描过的页面访问位都置\\&为0\\&第三轮:淘汰(0,0)\\&第四轮:淘汰(0,1)\\ \hline \end{array} OPTFIFOLURCLOCK(NUYR)CLOCK(NRU)访访访=0访1.(访),(0,0)(0,1),访0(0,0)(0,1)Belady

3.9 页面分配策略

3.9.1 驻留集

指请求分页存储管理中给进程分配的内存块的集合。

3.9.2 页面分配、置换策略

  • 固定分配 VS 可变分配: 区别在于进程运行期间驻留集大小是否可变
  • 局部置换 VS 全局置换: 区别在于发生缺页时是否只能从进程自己的页面中选择一个换出
  • 固 定 分 配 局 部 置 换 \color{red}固定分配局部置换 : 进程运行前就分配一定数量的物理块,缺页时只能换出进程自己的某一页
  • 可 变 分 配 全 局 置 换 \color{red}可变分配全局置换 : 只要缺页就分配新物理块,可能来自空闲物理块,也可能需要换出别的进程
  • 可 变 分 区 局 部 置 换 \color{red}可变分区局部置换 : 频繁缺页的进程,多分配一些物理块;缺页率很低的进程,回收一些物理块,直到缺页率合适

3.9.3 何事调入页面

  • 预调页面策略:一般用于进程运行前
  • 请求调页策略:进程运行时,发生缺页再调页

3.9.4 从何处调页

对换区----采用连续存储方式,速度更快;
文件区----采用离散存储方式,速度更慢;

  • 对换区足够大:运行将数据从文件区复制到对换区,之后所有页面调入、调出都是在内存与对换区之间进行
  • 对换区不够大:不会修改的数据每次都从文件区调入;会修改的数据调出到对换区,需要时再从兑换区调入
  • UNIX方式:第一次使用的页面都从文件区调入;调出的页面都写回对换区,再次使用时从对换区调出

3.9.5 抖动(颠簸)现象

页面频繁换入换出的现象, 主 要 原 因 是 分 配 给 进 程 的 物 理 块 不 够 \color{red}主要原因是分配给进程的物理块不够

3.9.6 工作集

在某段时间间隔里,进程实际访问页面的集合,驻留集大小一般不能小于工作集大小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值