对于一台x86(32bit)的操作系统来说,假设它有2G的物理内存,物理内存分成以许多个4k为单位大小的页框,这些页框就是存储进程的最小单位:
为了解决系统运行过程中不同进程之间内存的合理分配和利用,防止不同进程同一时刻在物理内存中运行而对物理内存的争夺和践踏(一旦某一进程失去控制,占用的资源不停增大,就会将物理内存占满,并导致其他进程中断,甚至导致服务器崩溃,这是及其危险的),我们采用了虚拟内存。
我们都知道,进程是用户发起的运行在内核之上的用户空间的程序,如下所示:
虚拟内存只是进程所看到的一个假象,实际进程运行过程中,进程还是通过物理内存上被CPU调用和执行的;线程是进程运行的最小单位,也是CPU运行和调用的最小单位。每一个进程可以包含多个线程,线程作为CPU调用的最小单位被映射到物理内存中,如下所示:
线程映射到物理内存后,物理内存会分配指定的页框给该线程,线程与页框之间的映射是随机的,非线性的。
随着进程的增加,线程的数量也会增加,物理内存的空间有限,页框将要用尽,物理内存空间几乎会被占满,接近与上限,这时如果继续运行下去,内存崩溃,服务器死机,将会产生不可预知的结果,那么该怎么解决这一问题呢?
于是,内核决定在硬盘上找一段存取速率较高的存储空间,模拟物理内存,并将其内部划分为类似页框的存储小格子。当物理内存接近崩溃时,将物理内存中最近一段时间最少频率使用到的页框移出物理内存,放进该存储空间,这段存储空间我们称之为交换空间(Swap)。当新创建的进程3进入内存时,发现当前物理内存已经被占满,此时内核便需要交换空间来协调,如下:
图中红色方块代表的线程为最近一段时间使用最不频繁的线程,
蓝色方块代表新创建的进程3包含的线程,黄色方块代表磁盘上的swap分区
a) 内核首先将红色线程移到swap分区,并取消进程1中该线程与物理内存的映射;
b) 随即,将蓝色线程移进物理内存中红色进程刚腾出的空间。此时,进程3就获得了系统内存资源,等待被CPU调用执行;
灰色进程代表当前内存中最近一段时间内使用最不频繁的线程
c) 当红色线程再次被唤醒时,内核会将灰色线程移到swap分区,取消该线程的映射;
d) 随即,内核将红色线程移进内存中灰色线程刚腾出的空间,并建立新的映射关系,获取系统内存资源。
swap分区存在的意义在于:允许内存过载(overcommit)使用
尽管swap分区可以为进程运行提供额外的交换空间,解决物理内存饱满情况下协调系统进程正常运行的问题,但是使用交换空间所带来的页框进出会大大降低系统的性能,所以应谨慎使用交换空间。
交换空间和物理内存之间页框的移动可以这样描述: