CS-Notes/docs/notes/计算机操作系统 - 内存管理.md
2019-10-28 00:20:30 +08:00

146 lines
7.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- GFM-TOC -->
* [虚拟内存](#虚拟内存)
* [分页系统地址映射](#分页系统地址映射)
* [页面置换算法](#页面置换算法)
* [1. 最佳](#1-最佳)
* [2. 最近最久未使用](#2-最近最久未使用)
* [3. 最近未使用](#3-最近未使用)
* [4. 先进先出](#4-先进先出)
* [5. 第二次机会算法](#5-第二次机会算法)
* [6. 时钟](#6-时钟)
* [分段](#分段)
* [段页式](#段页式)
* [分页与分段的比较](#分页与分段的比较)
<!-- GFM-TOC -->
# 虚拟内存
虚拟内存的目的是为了让物理内存扩充成更大的逻辑内存从而让程序获得更多的可用内存
为了更好的管理内存操作系统将内存抽象成地址空间每个程序拥有自己的地址空间这个地址空间被分割成多个块每一块称为一页这些页被映射到物理内存但不需要映射到连续的物理内存也不需要所有页都必须在物理内存中当程序引用到不在物理内存中的页时由硬件执行必要的映射将缺失的部分装入物理内存并重新执行失败的指令
从上面的描述中可以看出虚拟内存允许程序不用将地址空间中的每一页都映射到物理内存也就是说一个程序不需要全部调入内存就可以运行这使得有限的内存运行大程序成为可能例如有一台计算机可以产生 16 位地址那么一个程序的地址空间范围是 0\~64K该计算机只有 32KB 的物理内存虚拟内存技术允许该计算机运行一个 64K 大小的程序
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7b281b1e-0595-402b-ae35-8c91084c33c1.png"/> </div><br>
# 分页系统地址映射
内存管理单元MMU管理着地址空间和物理内存的转换其中的页表Page table存储着页程序地址空间和页框物理内存空间的映射表
一个虚拟地址分成两个部分一部分存储页面号一部分存储偏移量
下图的页表存放着 16 个页 16 个页需要用 4 个比特位来进行索引定位例如对于虚拟地址0010 000000000100 4 位是存储页面号 2读取表项内容为110 1页表项最后一位表示是否存在于内存中1 表示存在 12 位存储偏移量这个页对应的页框的地址为 110 000000000100
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/cf4386a1-58c9-4eca-a17f-e12b1e9770eb.png" width="500"/> </div><br>
# 页面置换算法
在程序运行过程中如果要访问的页面不在内存中就发生缺页中断从而将该页调入内存中此时如果内存已无空闲空间系统必须从内存中调出一个页面到磁盘对换区中来腾出空间
页面置换算法和缓存淘汰策略类似可以将内存看成磁盘的缓存在缓存系统中缓存的大小有限当有新的缓存到达时需要淘汰一部分已经存在的缓存这样才有空间存放新的缓存数据
页面置换算法的主要目标是使页面置换频率最低也可以说缺页率最低
## 1. 最佳
> OPT, Optimal replacement algorithm
所选择的被换出的页面将是最长时间内不再被访问通常可以保证获得最低的缺页率
是一种理论上的算法因为无法知道一个页面多长时间不再被访问
举例一个系统为某进程分配了三个物理块并有如下页面引用序列
```html
70120304230321201701
```
开始运行时先将 7, 0, 1 三个页面装入内存当进程要访问页面 2 产生缺页中断会将页面 7 换出因为页面 7 再次被访问的时间最长
## 2. 最近最久未使用
> LRU, Least Recently Used
虽然无法知道将来要使用的页面情况但是可以知道过去使用页面的情况LRU 将最近最久未使用的页面换出
为了实现 LRU需要在内存中维护一个所有页面的链表当一个页面被访问时将这个页面移到链表表头这样就能保证链表表尾的页面是最近最久未访问的
因为每次访问都需要更新链表因此这种方式实现的 LRU 代价很高
```html
47071012126
```
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eb859228-c0f2-4bce-910d-d9f76929352b.png"/> </div><br>
## 3. 最近未使用
> NRU, Not Recently Used
每个页面都有两个状态位R M当页面被访问时设置页面的 R=1当页面被修改时设置 M=1其中 R 位会定时被清零可以将页面分成以下四类
- R=0M=0
- R=0M=1
- R=1M=0
- R=1M=1
当发生缺页中断时NRU 算法随机地从类编号最小的非空类中挑选一个页面将它换出
NRU 优先换出已经被修改的脏页面R=0M=1而不是被频繁使用的干净页面R=1M=0
## 4. 先进先出
> FIFO, First In First Out
选择换出的页面是最先进入的页面
该算法会将那些经常被访问的页面也被换出从而使缺页率升高
## 5. 第二次机会算法
FIFO 算法可能会把经常使用的页面置换出去为了避免这一问题对该算法做一个简单的修改
当页面被访问 (读或写) 时设置该页面的 R 位为 1需要替换的时候检查最老页面的 R 如果 R 位是 0那么这个页面既老又没有被使用可以立刻置换掉如果是 1就将 R 位清 0并把该页面放到链表的尾端修改它的装入时间使它就像刚装入的一样然后继续从链表的头部开始搜索
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ecf8ad5d-5403-48b9-b6e7-f2e20ffe8fca.png"/> </div><br>
## 6. 时钟
> Clock
第二次机会算法需要在链表中移动页面降低了效率时钟算法使用环形链表将页面连接起来再使用一个指针指向最老的页面
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5f5ef0b6-98ea-497c-a007-f6c55288eab1.png"/> </div><br>
# 分段
虚拟内存采用的是分页技术也就是将地址空间划分成固定大小的页每一页再与内存进行映射
下图为一个编译器在编译过程中建立的多个表 4 个表是动态增长的如果使用分页系统的一维地址空间动态增长的特点会导致覆盖问题的出现
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/22de0538-7c6e-4365-bd3b-8ce3c5900216.png"/> </div><br>
分段的做法是把每个表分成段一个段构成一个独立的地址空间每个段的长度可以不同并且可以动态增长
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png"/> </div><br>
# 段页式
程序的地址空间划分成多个拥有独立地址空间的段每个段上的地址空间划分成大小相同的页这样既拥有分段系统的共享和保护又拥有分页系统的虚拟内存功能
# 分页与分段的比较
- 对程序员的透明性分页透明但是分段需要程序员显式划分每个段
- 地址空间的维度分页是一维地址空间分段是二维的
- 大小是否可以改变页的大小不可变段的大小可以动态改变
- 出现的原因分页主要用于实现虚拟内存从而获得更大的地址空间分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>