操作系统——虚拟内存篇

概念

内存管理策略的目标是:同时将多个进程保存在内存中,以便允许执行多个程序。然而,这些策略都倾向于要求每个进程在执行前完全处于内存中。
虚拟内存技术允许执行进程不必完全处于内存,它将逻辑内存和物理内存分离,允许进程轻松实现文件共享和内存共享。

实现原理
  1. 将磁盘上的空间分页,内存中的空间分页。
  2. 用户使用的是虚拟内存。
  3. 虚拟内存上的页对应的是内存或者磁盘空间上的页。
  4. 如果使用虚拟空间上的页,就会将这个页映射到内存的物理页上,如果这个页还在磁盘,就需要先加载到内存。
优势
  1. 将逻辑内存和物理内存分开,在现有的有限的物理内存下给程序员提供巨大的虚拟内存。
  2. 多个进程在虚拟内存中都用到了相同的共享库,每个进程在虚拟内存都加载了这个库,但是在物理内存中只有一个,虚拟内存的共享库都映射到了这一个库上面。
  3. 允许内存共享
虚拟地址空间

虚拟地址空间就是进程如何在内存中存放的逻辑视图(就是进程在虚拟内存中如何放置)。
从下到上:代码——数据——堆(向上增长)——栈(向下增长)
每个进程都是这样的连续的虚拟地址空间,但是通过映射对应到物理内存就不是连续的了。


实现细节

主要研究内存和磁盘通过页为单位换出换入,当使用页在磁盘中时,应该换入几个,内存满了以后,应该换出哪个页。

请求调页

仅在需要时候才加载页面,这种技术叫做请求调页。(但是预先也会加载一些大概率会用到的页到物理内存中)

概念

在逻辑内存和物理内存之间有一个页表,逻辑内存是0-7页,页表就有0-7项,其内容对应着物理内存中的地址,并且每项还有一个有效-无效位,无效代表物理内存中还没有加入需要的页(也就是,页还在磁盘中)。
当访问到无效的页表项,操作系统将磁盘数据加载到内存。

性能

缺页会发生的操作:

  1. 陷入操作系统
  2. 保存用户寄存器和进程状态
  3. 确定页面磁盘位置
  4. 从磁盘读入内存(加入磁盘IO队列,直到请求被处理,磁盘寻道读数据)
  5. 在CPU空闲阶段将CPU交给其他进程,当调页成功后,终止其他进程
  6. 等待CPU分给缺页进程
  7. 恢复上下文
    为了缺页可接受,40万次访问才能出现一次缺页。
请求调页需要解决的两个主要问题:固定数量的页如何分配给各种进程,页面置换时如何选择牺牲页
写时复制

系统通过fork()创建了一个父进程的复制,以作为子进程。使用写时复制技术,那么父进程和子进程共用相同的物理内存,这些页被标记为写时复制,意味着任何一个进程写入共享页面,那么就创建共享页面的副本。

页面置换

我们想将磁盘中的帧加载到内存页上,可能所有内存页都满了,那么就需要页面置换。

基本页面置换

方案一:找空闲页,如果没有就使用页面置换算法选择一个牺牲页,将牺牲页写入磁盘,就目标页写入牺牲页的位置。
方案二:页采用修改位,没修改的页不写回磁盘中。
页面置换算法:如果硬件支持LRU,则使用LRU,否则就只能使用FIFO算法或者LRU的近似算法了。

FIFO页面置换算法

FIFO页面置换算法为每个页面记录了调到内存的时间,当必须要置换时,将选择最旧的页。

最优页面置换算法

置换最长时间不会使用的页面。
但是因为要预测将来,难以实现。

最优页面置换算法的近似——LRU页面置换算法(Lasted-Recent-Used)

将最近的过去作为将来的近似,从而置换最长时间没使用的页。
也叫做最近最少使用算法。
LRU需要硬件支持,是一个常用的页面置换算法。
实现:

  1. 计数器方案:CPU添加一个逻辑时钟,每次内存引用都会递增,当页面引用时,会将值写入页中,我们只需要置换时间数最小的页就行了。
  2. 栈方案:最近最少使用的页在栈低。
没有LRU实现的硬件,用FIFO实现最近最少使用的思想

原理:为那些修改的页赋予更高级别,从而降低IO数量
实现:

  1. 额外引用位算法:一个8位的页面引用位,一个时间周期左移,如果被引用了就加1,
  2. 二次机会算法:引入引用位,但是是一位,但是被引用后有二次机会,FIFO遍历到时候,会有一次免死机会(将引用位1-》0)。
  3. 增强型二次机会算法:引入修改位和引用位(0,0),(0,1)。。。。FIFO遍历。
页面缓冲算法

除了页面置换算法,操作系统还会采用其他措施。
例如,系统通常保留一个空闲页缓冲池。在选出牺牲页之前就将目标页写入到缓冲页中了,这种措施允许进程尽快重新启动,而无需等待写出牺牲帧。
保留一个空闲页池。

应用程序与页面置换:如果应用程序实现了自己的内存使用逻辑,那么就不应该用操作系统的了

在某些情况下,应用程序有自己的内存实现逻辑,此时操作系统再使用虚拟内存反而会导致效率下降。比如数据库。
对于这些问题,操作系统分出了原始磁盘,原始IO绕过了文件系统,使用数据库的实现原理,从而提高效率。

页分配

在各个进程之间,如何分配固定数量的可用内存,从而最少缺页。

分配算法

平均分配和按照进程大小的比例分配和按照优先级的比例分配。
通常使用的就是优先级比例分配的。

页面置换:全局置换与局部置换

全局置换就是能将所有进程中的适合页作为牺牲页。
局部置换只能将自己进程中的页作为牺牲页。
全局置换会有更好的系统吞吐量,因此是更常用的算法。

系统抖动

高度的页面调度。
通过局部置换算法或优先权置换算法可以限制系统抖动。

内存映射文件

当用户打开一个文件后,操作系统通常会使用虚拟内存来管理内存和磁盘之间的数据交互。

你可能感兴趣的:(操作系统,linux,服务器,系统架构,ubuntu,windows)