首页 > 编程笔记

Linux内存管理详解

所有进程(执行的程序)都必须占用一定数量的内存,它有时候是用来存放从磁盘载入的程序代码,有时候是存放用户输入的数据等。

物理内存和虚拟内存

物理内存就是系统硬件的内存大小,是系统真正的内存。

相对于物理内存而言,在 Linux 系统下还有虚拟内存,所谓的虚拟内存就是为了满足物理内存的不足而提出的策略。虚拟内存就是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(swap space)

虚拟内存是物理内存的扩展,当系统中的物理内存不足时,就会使用交换分区的虚拟内存。内核会把系统中暂时不需要的内存块信息存储到交换空间,从而释放了物理内存,因此物理内存可以作用于其他地方,当需要使用到原始的内容时,这些信息会被重新从交换空间读入物理内存。

Linux 系统内存管理常用的方法有 2 个:
  1. 调页算法是将内存中最近不经常使用的页面交换到磁盘上,把经常使用的页面保留在内存中供进程使用。
  2. 交换技术是系统将整个进程,全部交换到磁盘上,注意不是部分页面。正常情况下,系统会发生一些交换过程。

当物理内存严重不足时,系统会频繁使用调页和交换,虽然使用虚拟内存扩大了内存的容量,但却增加了磁盘 I/O 的负载。进一步降低了系统对作业的执行速度,即系统 I/O 资源问题又会影响到内存资源的分配。

注意,对于 Linux 系统的内存管理,通常采用的是分页存取机制。为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。

物理内存地址与虚拟内存地址

计算机对虚拟内存地址空间(32 位为 4GB)进行分页,产生页(page);对物理内存地址空间进行分页,产生页帧(page frame)。页和页帧的大小相同,但虚拟内存页的个数必须要大于物理内存页帧的个数。

另外在计算机上还有一个页表(page table),主要用来映射虚拟内存页到物理内存页,即是页号到页帧号的映射,而且是一对一的映射。

在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和 BSS 段的加载,并在内存中为这些段分配空间。栈也由操作系统分配和管理;堆由程序员自己管理,即显式地申请和释放空间。BSS段、数据段和代码段是可执行程序编译时的分段,运行时还需要栈和堆。该过程的特点如下:
  1. 每个进程都有自己独立的 4GB 内存空间,各个进程的内存空间具有类似的结构;
  2. 每个进程的 4GB 内存空间都只是虚拟的内存空间,每次访问内存空间的某个地址时,都需要把地址翻译为实际物理内存地址;
  3. 所有进程共享同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上;
  4. 一般认为虚拟空间全部被映射到了磁盘空间中,并且由页表记录映射位置。

交换空间的使用

交换空间是现代 Linux 系统中的第二种内存类型。交换空间的主要功能是当全部的 RAM 被占用并且需要更多内存时,用磁盘空间代替 RAM 内存。

Linux 系统通常使用交换空间来增加主机可用的虚拟内存量。它可以在常规文件系统或逻辑卷上使用一个或多个专用交换分区或交换文件。

Linux 提供了两种类型的交换空间。默认情况下,大多数 Linux 系统的安装都会创建交换分区,但也可以使用特殊配置的文件作为交换文件。交换分区是一个标准的磁盘分区,由 mkswap 命令。

如果没有可用的磁盘空间来创建新的交换分区,则可以使用交换文件。这只是一个常规的文件,它被创建并预先分配到指定的大小,然后 mkswap 命令将其配置为交换空间。

在 Linux 系统中,虚拟内存被称为系统交换区(swap)。而 Linux 系统的 swap 区又分为两种:
  1. 使用划分好的分区作为 swap 区;
  2. 使用 Linux 系统的文件作为 swap 区。

要在 Linux 系统上创建一个 swap 区(虚拟内存),需要执行这样几个操作:

注意,如果虚拟内存使用的是 swap 分区,需要使用 swapon -a 命令来启用该分区。这是因为 swapon -a 命令会读取 /etc/fstab 文件中所有有关 swap 的记录,并且启用所有的 swap 分区。如果使用的是 swap 文件,则使用 swapon swapfile(swap 的文件名)来启用。另外,还可以使用 swapon -s 命令来查看 swap 分区或文件的状态信息。

Linux系统中交换空间的使用

Linux 系统会有频繁的页面交换操作,这样是为了让更多的物理空间保持空闲,即使现在不需要内存,Linux 系统也会交换出暂时不需要使用的内存页面以减少等待交换所需的时间。

Linux 系统在进行页面交换时是有条件的。不是所有的页面在不使用时都能够交换到虚拟内存中,Linux 内核根据“最近最经常使用”算法,只将一些不经常使用的页面文件交换到虚拟内存,这可能会出现 Linux 物理内存还有很多,但是交换空间也使用了很多的现象。

这是因为当一个需要占用很大内存的进程在运行时,需要耗费很多的内存资源,此时就会有一些不常用的页面文件被交换到虚拟内存中;最后当这个占用很多内存资源的进程结束并且释放了较多的内存时,被交换出去的页面文件并不会自动交换到物理内存,此时系统的物理内存就会空闲很多,但交换空间还处于正在被使用的状态。

交换空间的页面在使用时会最先被交换到物理内存,如果此时没有足够的物理内存来存放这些页面,那么这些页面又会被交换出去。因此,虚拟内存中可能没有足够的空间来存放这些交换页面,最终会导致 Linux 出现假死机、服务异常等问题,Linux 系统虽然可以在一段时间内自动恢复,但是恢复后的系统已经基本上不能使用了。

交换空间的大小

当 Linux 系统中的物理内存很大时,可能没有交换空间系统也能很好地运行。但当物理内存使用完时,系统就会崩溃,因为它没有可以释放内存的方式,因此在系统中提供一个交换空间也是很有必要的。那么交换空间通常多大合适呢?

具体如下:

优秀文章