大家好 我是积极向上的湘锅锅💪💪💪
操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情
总结来说:如果直接把物理地址暴露出来的话会带来严重问题,比如可能对操作系统造成伤害以及给同时运行多个程序造成困难
首先思考为什么要有虚拟地址空间呢?
假设没用虚拟地址空间,程序直接访问和操作的都是物理内存 ,会产生什么问题?
通过虚拟地址访问内存有以下优势:
每个进程创建加载的时候,会被分配一个大小为4G的连续的虚拟地址空间,虚拟的意思就是,其实这个地址空间时不存在的,仅仅是每个进程“认为”自己拥有4G的内存,而实际上,它用了多少空间,操作系统就在磁盘上划出多少空间给它,等到进程真正运行的时候,需要某些数据并且数据不在物理内存中,才会触发缺页异常,进行数据拷贝
用户态和内核态:
为了使操作系统内核提供一个无懈可击的进程抽象,处理器必须提供一种机制,限制一个应用可以执行的指令以及它可以访问的地址空间范围
处理器通常是用某个控制寄存器中的一个模式位来提供这种观功能的,该寄存器描述了进程当前享有的特权。
为什么需要虚拟内存?
那操作系统该如何管理虚拟地址与物理地址的关系?
go on reading
段式管理把主存分为一段段的,段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址
程序中的地址是一个偏移量,在载入的时候,找到一个逻辑地址的基址(找到一个空间段),加上该偏移量,得到一个逻辑地址,再映射到物理地址,这个过程就是载入重定位(第一次载入)
运行时重定位:操作系统中有进程的切换,之前载入的程序可能阻塞(被交换到硬盘)一段时间之后重新载入内存,之前的重定位方法就不可行了,因此程序还是先载入偏移量,在某条指令运行的时候再加上基址,进行重定位
程序的分段:
分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护
在内存分段之后,整个程序就流程如下:
因为程序的每一个段大小都是不固定的,所以需要寻找一个合适的分区,有三种方案
对比:
可以看出前俩种需要O(n)也就是找出所有分区里面的最大最小
而首先适配最差才是O(n),最好是O(1),但是碎片化就比较严重
问题:
CPU寻址:CPU 需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件
如何解决上述问题?
OS引入分页,将固定大小页面做为分配的单位,就不会有碎片了(页内碎片很小)
把主存分为大小相等且固定的一页一页的形式,页较小,相比于块式管理的划分粒度更小,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址
这个时候页面的大小就要适中了,过大难以分配,过小内存碎片过大,页面大小通常是512B-8K
对于32位寻址的虚拟地址,如果页面大小为4KB,则虚拟页面数最多可以达到2的20次方,即1048576个虚拟页面,那么页表的记录条数就为1048576条,所以引入多级页表
引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。多级页表属于时间换空间的典型场景,具体实现思想参考数据库的索引
为何可以节省空间?
如何提升虚拟地址到物理地址的转换速度?
引入快表,我们可以把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的 Cache,它的作用与页表相似,但是提高了访问速率。由于采用页表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度,就好比Redis缓存模式,查询缓存总比磁盘快上不少
使用快表之后的地址转换流程是这样的:
总结:为了提高内存的空间性能,提出了多级页表的概念;但是提到空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表(即 TLB)的概念。 不论是快表还是多级页表实际上都利用到了程序的局部性原理,局部性原理在后面的虚拟内存这部分会介绍到
共同点 :
分页机制和分段机制都是为了提高内存利用率,减少内存碎片。
页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内存是连续的。
区别 :
页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序。
分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满足用户的需要。
分页和分段管理方式各有其优缺点,分页系统能有效提高内存的利用率,而分段则能更好地满足用户的需要,因此可以将两者结合成一种新的存储管理方式系统称为“段页式存储管理”
结合分段和分页思想
段页式系统中,获得一条指令或数据需要访问三次内存
地址映射过程中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断 。
当发生缺页中断时,如果当前内存中并没有空闲的页面,操作系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫做页面置换算法,我们可以把页面置换算法看成是淘汰页面的规则
这篇更加详细 页面置换算法