看王道做的笔记,结合一些自己的思考,还有一些找到的资料和刷题经验,但只是为了应付半期考,所以不全
编译,链接,装入
装入方式
绝对装入
装入绝对地址
只适合单道系统使用
静态重定位(可重定位装入)
装入时转换,装入就不可移动
不灵活
动态重定位(动态运行时装入)
利用重定位寄存器,运行时转换,便于修改和更新,可以共享模块
内存保护
通过界地址寄存器进行越界检测
扩充方法
覆盖
按调用的树把不相关的覆盖掉,但对用户不透明,现在不用
交换
使用中级调度算法,就是内存调度算法,可以去第二篇那里找一找
把外存分成对换区和文件区,前者连续分配,I/O 快,后者空间利用率高
PCB 不会进外存
虚拟存储
内存分配
内部碎片:
分配了,但没有用上
连续
单一,即只能跑一个,没有外部碎片(都分了,怎么出现外部碎片)
固定大小分区,大小可以不一样,没有外部碎片(事先都分好了,怎么出现外部碎片)
动态内存分区
空闲分区表
回收时,和相邻的空闲分区合并
存在外部碎片,因为可能太小太碎,已经利用不上了
可以通过紧凑技术解决,记得改 PCB 的起始位置
没有内部碎片,因为分配的都是程序需要的
算法
首次适应:(其实最好用)
从低地址开始暴力搜索,找到就用
高地址容易有大分区
最佳适应:分区按容量排
找到一个比要求大,但多的最少的,问题是外部碎片很多
最坏适应:分区按容量排
Largest First,最大优先,但连续分区很快就用完了
邻近适应:
相当于首次适应算法,但从上一次结束的位置开始,利用率更高,但高地址的大分区没了
非连续
时间局部性(循环)和空间局部性(下一个范围有限)
分页式
事先定好,没有外部碎片
物理内存的分区:
页框=页帧=内存块=物理块=物理页面
分区的编号:
页框号=页帧号=内存块号=物理块号=物理页面号
从零开始
逻辑地址空间大小和页框一样,叫页或者页面,编号叫页号
分区 | 编号 | |
---|---|---|
物理 | 页框=页帧=内存块=物理块=物理页面 | 页框号=页帧号=内存块号=物理块号=物理页面号 |
逻辑 | 页=页面 | 页号 |
PCB里有页表
一行页表项:
页号 | 块号(页框号) |
---|
页表项比特数为就是块号(页框号)字节数,因为页表连续,页号相当于数组序号,注意转换成字节要除以8
逻辑地址为页号+页内偏移量(一定顶着末尾)
前者可以算页数,后者可以算页面大小
为了方便查找,可能会让页表项占用更多字节,如一个页表也是用一个页框做的
通常Cache块的大小会比主存页框的大小更小一些
但在408考试当中,主存块和Cache块的大小是相同的**,但是页的大小和Cache块的大小是不同**的
小心按字节编码
页表大小=页大小*页表项数
访存次数比页表层数多一
快表
大小大概是4KB,命中率大概在90%左右
联想寄存器,TLB(translation lookaside buffer),是寄存器,相当于特殊的cahce
注意和内存访问是否同时
二级页表
页表大小不超页框大小
因为局部性,只会有部分页表访问
所以可以用二级页表,然后就不需要这么大的连续空间了,同时节约资源,甚至可以把页表放到外存
分段式
按需分配,没有内部碎片
从零开始
有段名,在汇编时使用方便,会被翻译成段号,对应
段表有==段长==+基址(位数用物理地址大小算)
段长不一,但段表项长度相同,所以没有记段号
越界查两次,一次端号,一次段内地址(在算物理地址前)
定位要段号和端内地址,是二维的(数组)
可以实现信息的共享和保护,如纯代码(可复入代码)(不能修改的代码)(不是临界资源)
段页式
逻辑地址:段号+页号+偏移量
段可见,但页不可见
段表隐藏,段表项长度相同,存的是页表的长度和页表块号(页表的起始地址)(就是把原来存着物理地址替换成页表的值)
也就是说,一个段就是一个页表
一个进程只有一个段表,但一般有多个页表
页表一样
越界检测:段号和段表长度,结果页号和段表里的页表长度
三次访存
虚拟内存
多次调入,对换,虚拟
不在内存,请求调页
和页表相关
- 页表上多了在哪,访问字段,脏位,外存地址
- 缺页中断,一条指令可能多次中断,用内中断,属于“故障”
- 地址变换,多检测是否在内存,不在就调页,可能还要把其他的换出内存才够,调入后会修改页表项
空间不够,页面置换
- OPT
- FIFO
- LRU
- CLOCK(NRU)
没有脏位 - 改进型CLOCK