可用内存为什么可以超过实际内存

一、虚拟CPU和虚拟内存:

1、虚拟cpu:

利用进程机制,所有的现代操作系统都支持在同一时间来完成多个任务。尽管某个时刻,真实的CPU只能运行一个进程,但是从进程自己的角度来看,它会认为自己在独享CPU(即虚拟CPU),而从用户的角度来看多个进程在一段时间内是同时执行的,即并发执行。在实际的实现中,操作系统会使用调度器来分配CPU资源。调度器会根据策略和优先级来给各个进程一定的时间来占用CPU,进程占用CPU时间的基本单位称为时间片,当进程不应该使用CPU资源时,调度器会抢占CPU的控制权,然后快速地切换CPU的使用进程。这种切换在用户的视角中对程序执行毫无影响,可以认为是透明的。由于切换进程消耗的时间和每个进程实际执行的时间片是非常小的,以至于用户无法分辨,所以在用户看来,多个进程是在同时进行的。

1.1、调度器和优先级:

Linux内核存在一个专门用来调度进程的内核线程,称为调度器。调度器的基本工作是从一组处于可执行状态的进程中选择一个来执行,Linux提供了抢占式的多任务模式。调度器会决定某个进程在什么时候停止运行,并且可以让另一个线程进入执行,这个动作即所谓的抢占

传统的Linux操作系统采用的时间片轮转法。这种方法的大致流程是:调度器它把所有的可运行的非实时的进程组织在一起,这个数据结构被称为就绪队列。通常调度器取一个固定时间作为调度周期,当一个调度周期开始的时候,调度器回味就绪队列当中的每个进程分配时间片,每个进程能够获取的时间片长度和进程的优先级有关。正在执行的进程会在执行的过程中逐渐消耗它的时间片,当时间片耗尽时,如果该进程仍然处于运行状态,那么它就会被就绪队列中的下一个进程抢占。如果整个调度周期执行完成,调度器就会抢占该进程,并且根据优先级分配新的时间片。

在进程执行过程中,会出现等待IO操作的情况。此时,进程就会从就绪队列当中移除,并且将其放入等待队列,并且将自己的状态调整为等待状态。进程运行终止时,进程也会从就绪队列中移除。

当进程被创建或者被从等待状态唤醒时,调度器会根据优先级分配时间片,再将其插入到就绪队列当中。

二、虚拟内存

在进程本身的视角中,它除了会认为CPU是独占的以外,它还会以为自己是内存空间的独占者,这种从进程视角看到的内存空间被称为虚拟内存空间。当操作系统中有多个进程同时运行时,为了避免真实的物理内存访问在不同进程之间发生冲突,操作系统需要提供一种机制在虚拟内存和真实的物理内存之间建立映射

二、fork的写时复制:

当执行了fork了以后,父子进程地址空间的内容是完全一致,所以完全可以共享同一片物理内存,也就是父子进程的同一个虚拟地址会对应同一个物理内存字节。通常来说,内存的分配单位是页,我们可以为每一个内存页维持一个引用计数。代码段的部分因为只读,所以完全可以多个进程同时共享。而对于地址空间的其它部分,当进程对某个内存页进行写入操作的时候,我们再真正执行被修改的虚拟内存页分配物理内存并拷贝数据,这就是所谓的写时复制。在执行拷贝以后,同样的虚拟地址就无法对应同样的物理内存字节了。

再探写时复制:
当父进程使用fork创建了一个子进程以后,操作系统需要为子进程拷贝一份父进程的页表到内存当中(基本这是系统调用最令人烦恼的开销)。当子进程的某个可以写入的页被第一次写入的时候,内核会意识到对应的物理页是属于父进程的,此时会为子进程分配一个新的物理页,如果要分配的物理页不在主存储器中,此时会出发一个异常名为缺页异常,当异常处理完成以后,子进程会被分配一个新的物理页,并且物理页内容会是原来页的拷贝。这就是所谓的写时复制。

相关推荐

  1. 可用内存为什么可以超过实际

    2024-07-17 01:28:02       21 阅读
  2. x-mind没有配置文件,可以自己创建文件修改

    2024-07-17 01:28:02       53 阅读
  3. 内存和堆

    2024-07-17 01:28:02       40 阅读
  4. 为什么 GraphQL 可以取代 Redux?

    2024-07-17 01:28:02       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 01:28:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 01:28:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 01:28:02       58 阅读
  4. Python语言-面向对象

    2024-07-17 01:28:02       69 阅读

热门阅读

  1. 安全运营概述

    2024-07-17 01:28:02       22 阅读
  2. $@和$?在shell脚本中什么意思

    2024-07-17 01:28:02       21 阅读
  3. 前端面试题日常练-day92 【Less】

    2024-07-17 01:28:02       20 阅读
  4. Map和Set的迭代器原理

    2024-07-17 01:28:02       20 阅读
  5. tomcat为什么要自定义类加载器?

    2024-07-17 01:28:02       21 阅读
  6. Web 安全之 VAPT (漏洞评估与渗透测试)详解

    2024-07-17 01:28:02       21 阅读
  7. VScode编译c++代码json配置

    2024-07-17 01:28:02       24 阅读