20145324 《信息安全系统设计基础》第十四周学习总结
教材学习内容总结
•虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的和私有的地址空间
•程序员需要理解虚拟存储器的原因:
①虚拟存储器是中心的
②虚拟存储器是强大的
③虚拟存储器若操作不当则十分危险
物理和虚拟寻址
•计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每字节都有一个唯一的物理地址
•计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每字节都有一个唯一的物理地址PA。根据物理地址寻址的是物理寻址。
地址空间
•线性地址空间:地址空间中的整数是连续的
•虚拟地址空间:CPU从一个有 N=2^n 个地址的地址空间中生成的虚拟地址
•物理地址空间:与系统中的物理存储器的M个字节相对应
虚拟存储器作为缓存的工具
•每个字节都有一个唯一的虚拟地址
•每个虚拟页大小为P=2^p字节
•在任意时刻,虚拟页面的集合都被分为三个不相交的子集:
①未分配的:VM系统还没分配/创建的页,不占用任何磁盘空间
②缓存的:当前缓存在物理存储器中的已分配页
③未缓存的:没有缓存在物理存储器中的已分配页
•物理存储器被分割为物理页(PP),也叫页帧,大小也为P字节
DRAM缓存的组织结构
•DRAM缓存来表示虚拟存储器系统的缓存
•DRAM缓存的组织结构完全是由巨大的不命中开销驱动的
•DRAM缓存总是使用写回,而不是直写
•页表:是一个数据结构,存放在物理存储器中,将虚拟页映射到物理页,就是一个页表条目的数组
•页表就是一个页表条目的数组
•PTE:由一个有效位和一个n位地址字段组成的
•DRAM缓存不命中称为缺页
•在磁盘和存储器之间传送页的活动叫做交换或者页面调度
•颠簸:工作集大小超出了物理存储器的大小
虚拟存储器作为存储器管理工具
•多个虚拟页面可以映射到同一个共享物理页面上
•简化链接:独立的地址空间允许每个进程的存储器映像使用相同的基本格式,而不管代码和数据实际存放在物理存储器的何处
•简化加载:虚拟存储器使得容易想存储器中加载可执行文件和共享对象文件
•简化共享:独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制
•简化存储器分配:虚拟存储器为向用户进程提供一个简单的分配额外存储器的机制
虚拟存储器作为存储器保护的工具
•PTE的三个许可位:
SUP:表示进程是否必须运行在内核模式下才能访问该页
READ:读权限
WRITE:写权限
地址翻译
•地址翻译:一个N元素的虚拟地址空间(VAS)中的元素和一个M元素的物理地址空间(PAS)之间的映射
•CPU中的一个控制寄存器页表基址寄存器指向当前页表
•n位的虚拟地址包含两个部分:一个p位的虚拟页面偏移(VPO) 和一个(n-p)位的虚拟页号
•页表条目中的物理页页号和虚拟地址中的VPO串联起来,就得到了相应的物理地址
•主要思路:地址翻译发生在高速缓存之前
•每次CPU产生一个虚拟地址,MMU就必须查阅一个PTE
•TLB:翻译后备缓冲器,是一个小的、虚拟存储的缓存,其中每一行都保存着一个由单个PTE组成的块
案例研究
•PTE的三个权限位:
R/W位:确定内容是读写还是只读
U/S位:确定是否能在用户模式访问该页
XD位:禁止执行位,64位系统中引入,可以用来禁止从某些存储器页取指令
•缺页处理程序涉及到的位:
A位,引用位,实现页替换算法
D位,脏位,告诉是否必须写回牺牲页
•内核虚拟存储器包含内核中的代码和数据结构,还有一些被映射到一组连续的物理页面
•linux将虚拟存储器组织成一些区域(也叫做段)的集合。一个区域就是已经存在的(已分配的)虚拟存储器的连续片
•内核不用记录那些不存在的页,这样的页也不用占用存储器
存储器映射
•存储器映射:Linux通过将一个虚拟存储器区域与一个磁盘上的对象关联起来,以初始化这个虚拟存储器区域的内容的过程
•映射对象:
①Unix文件系统中的普通文件
②匿名文件
•旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件之间换来换去。交换文件也叫交换空间,或交换区域
•共享对象:
共享对象对于所有把它映射到自己的虚拟存储器进程来说都是可见的。即使映射到多个共享区域,物理存储器中也只需要存放共享对象的一个拷贝
•私有对象:
私有对象运用的技术:写时拷贝。在物理存储器中只保存有私有对象的一份拷贝
•当fork函数被当前进程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID
•使用execve函数将a.out程序加载并运行所需要的步骤如下:
①删除已存在的用户区域。
②映射私有区域。
③映射共享区域。
④设置程序计数器。
•Unix进程可以使用mmap函数来创建新的虚拟存储器区域,并将对象映射到这些区域当中
动态存储器分配
•当运行时需要额外虚拟存储器时,使用动态存储器分配器维护一个进程的虚拟存储器区域
•分配器有两种风格:
显示分配器:要求应用显式地释放任何已经分配的块
隐式分配器:要求分配器检测一个已分配块何时不再被程序所使用,就释放这个块。也叫做垃圾收集器
•系统调用malloc函数,从堆中分配块
•系统调用free函数来释放已分配的堆块
•显示分配器的要求:
①处理任意请求序列
②立即响应请求
③只使用堆
④对齐块
⑤不修改已分配的块
•目标:
①最大化吞吐率:最大化存储器利用率——峰值利用率最大化
②吞吐率:每个单位时间里完成的请求数
•碎片:虽然有未使用的存储器,但是不能用来满足分配请求
•内部碎片:发生在一个已分配块比有效载荷大的时候,易于量化
•外部碎片:发生在当空闲存储器合计起来足够满足一个分配请求,但是没有一个单独的空间块足以处理这个请求时发生。难以量化,不可预测
•分配方式有:
①首次适配:从头开始搜索空闲链表,选择第一个合适的空闲块
②下一次适配:从上一次搜索的结束位置开始搜索
③最佳适配:检索每个空闲块,选择适合所需请求大小的最小空闲块
•合并是针对于假碎片问题的,任何实际的分配器都必须合并相邻的空闲块
•合并的两种策略:
①立即合并
②推迟合并
•简单分离存储:
每个大小类的空闲链表包含大小相等的块,每个块的大小就是这个大小类中最大元素的大小
优点:分配和释放块快
缺点:容易造成碎片
•分离适配:
分配一个块:确定请求的大小类,对适当的空闲链表做首次适配,查找一个合适的块,找到一个之后,可选的分割它,并将剩余部分插入适当的空闲链表中,如果找不到合适的块,就搜索下一个更大的大小类的空闲链表,直到找到一个合适的块,如果没有合适的块,就向操作系统请求额外的堆存储器,并从这个新的堆存储器中分配出一个块,将剩余部分放置在适当的大小类中,释放块时,执行合并,并将结果放置在相应的空闲链表里
•伙伴系统:
伙伴系统是分离适配的一种特例,每个大小类都是2的幂
优点:快速搜索和快速合并
缺点:内部碎片
•垃圾收集器:一种动态存储分配器,它自动释放程序不再需要的已分配块,这些块被称为垃圾,自动回收堆存储的过程叫做垃圾收集
课后作业中的问题和解决过程
①练习题9.4:
已开始做的时候有点找不到方向,但是参考前面课文中的例子就可以解决。但是最后一个返回的缓存字节还是不知道怎么算的
②练习题9.7:
不知道怎么算的
实践
这周老师没有发代码,实践应该就是书上的代码吧
•先写好代码
•再把.h文件移到/usr/include下面
•编译运行
本周代码托管截图
http://git.oschina.net/SJZGM10/CSAPP2E/tree/master/src/09vm?dir
其他(感悟、思考等,可选)
这是这学期自学的最后一章,相比上学期的java,我觉得自己这学期的学习态度有了改变,没有那么消极了。所以自己也真的学到了一些知识,当然最熟悉的还是虚拟机的操作。虽然很累吧,但是也还是值得,就是写博客真的太令人伤神了。
学习进度条
博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|
目标 | 30篇 | 400小时 | |
第零周 | 1/1 | 20/20 | |
第一周 | 1/2 | 20/40 | |
第二周 | 1/3 | 20/60 | |
第三周 | 1/4 | 20/80 | |
第四周 | 1/5 | 20/100 | |
第五周 | 1/6 | 20/120 | |
第六周 | 1/7 | 20/140 | |
第七周 | 1/8 | 20/160 | |
第八周 | 5/13 | 20/180 | |
第九周 | 1/14 | 20/200 | |
第十周 | 1/15 | 20/220 | |
第十一周 | 1/16 | 20/240 | |
第十二周 | 1/17 | 20/260 | |
第十三周 | 1/18 | 20/280 | |
第十四周 | 1/19 | 20/300 |