性能优化理论篇 | swap area是个什么东西

我们知道每台计算机的内存(RAM)都是有限的,而我们的应用程序需要加载到内存才能被运行,如果一台机器运行多个应用程序时,内存可能会耗尽。Linux 系统中的"交换空间(也称为交换分区)"可以帮助缓解内存不足的问题。

其实对于交换空间,如果能弄清楚以下几个疑问,那么对交换空间的理解也就差不多了。

  • 什么是交换空间 ?

  • 为什么需要交换空间?

  • 如何查看交换空间大小?

  • Linux 需要交换空间吗?

  • 机器的 RAM容量很大,还需要交换空间吗?

  • Linux 系统应该配置多大的交换空间?

  • 交换空间如何工作?

  • 频繁交换导致的性能问题

  • 如何在 Linux 中增加交换空间?

什么是交换空间 ?

从物理层面(存储层面)看,交换空间只是辅助存储器(Secondary Memory,如硬盘)上的一个特殊区域,用于在 系统内存 不足时临时存储数据,此时,操作系统会将一些不常使用的数据从 内存 中移出,暂时存放在这个交换空间中,以腾出 内存 空间给需要的程序。

从虚拟内存的概念来看,交换空间是虚拟内存的一部分。

虚拟内存是操作系统通过将物理内存(RAM)和硬盘上的交换空间结合起来使用的一种机制。它让系统可以假装拥有比实际物理内存更多的内存资源。

为什么需要交换空间?

我们已经了解了交换空间是什么,接下来看看为什么交换空间对于系统来说是必需的:

  1. 低配置机器:如果机器的 内存 很小,例如只有 1GB 或更少,那么交换空间是必不可少的,因为大多数应用程序可能会耗尽这点 内存,如果没有交换分区,这台机器可能连一个应用程序都运行不起来。

  2. 防止系统崩溃:当系统内存耗尽时,如果没有交换空间,操作系统可能会无法再分配内存给新进程或需要更多内存的进程,这可能导致系统崩溃。有了交换分区,遇到这种情况时,系统可以暂时将一些不常用的数据移到交换空间,以腾出内存,避免系统整体崩溃。

总结一下,交换空间的作用,就像是安全带( safety belt),如果有进程悄无声息地消耗越来越多的内存(比如内存泄漏 Memory Leak),内存吃不消的情况下,没关系,还有交换空间这个缓冲区。操作系统会帮你将某些内存置换到交换空间,来满足你的需求,直到交换空间也顶不住了为止。

假如没有交换空间,操作系统的OOM大神就会嘎崩脆地杀死了一些进程,但是这些被杀的进程,不一定就是你想让它们死的进程。有了交换空间,在内存吃紧的情况下,你就会发现你的机器变慢了,反应很迟钝,很卡。这是因为原本正常情况下访问内存的操作,不得不先将磁盘上内容置换进入内存。这种很卡本身会给你提示,给你一个时间,给你一个机会,让你在交换空间 也耗尽之前,干掉你真正想干掉的进程。

为了理解上面的内容,这里做个小实验。

启动一个不断消耗内存的程序,看下linux如何应对这个进程。程序代码如下:

c 复制代码
int main(int argc, char** argv)
{
    int max = -1;
    int mb = 0;
    char* buffer;

    if(argc > 1)
        max = atoi(argv[1]);

    while((buffer=malloc(10*1024*1024)) != NULL && mb != max)
    {
        memset(buffer, 0,10*1024*1024);
        mb = mb + 10;
        printf("Allocated %d MB\n", mb);
        sleep(1);
    }
    return 0;
}

首先我将交换空间 用swapoff -a 清空,然后swapon -a打开,然后执行这个程序。

sh 复制代码
root@manu-hacks:~/code/c/self/swap# swapoff -a
root@manu-hacks:~/code/c/self/swap# free -m
             total       used       free     shared    buffers     cached
Mem:          1942       1731        210          0         38        281
-/+ buffers/cache:       1411        530
Swap:            0          0          0

猜猜看,这个进程最多能分配多少内存?现在看起来free的只有530M ,这已经算上了cached的内容,也就是说,我们最多哪怕把所有的file cache也占用掉,也不过是能够分配530M的内存。事实上是这样吗?

sh 复制代码
root@manu-hacks:~/code/c/self/swap# swapon -a ;  free -m ; ./eat_mem 
             total       used       free     shared    buffers     cached
Mem:          1942       1741        200          0         38        282
-/+ buffers/cache:       1421        521
Swap:         3907          0       3907
Allocated 10 MB
Allocated 20 MB
Allocated 30 MB
Allocated 40 MB
Allocated 50 MB
Allocated 60 MB
Allocated 70 MB
Allocated 80 MB

.......
Allocated 3020 MB
Allocated 3030 MB
Allocated 3040 MB
Allocated 3050 MB
root@manu-hacks:~/code/c/self/swap#
root@manu-hacks:~/code/c/self/swap#

我们看到,实际上,分配了3050MB,才被杀死。这个过程中,cache中内容被驱逐,cache越来越小,而Swap used部分越来越多,越来越多的内容被置换到swap area 。感兴趣的筒子可以用 watch 'free -m' 查看这个内存的变换过程,很有意思。

如何查看交换空间大小?

查看交换空间的大小以及使用情况,一般使用free命令即可,如下所示:

sh 复制代码
qin@linux-01:~$ free -h
              total     used     free      shared  buff/cache   available
Mem:        15Gi       4.7Gi    6.3Gi       986Mi     4.5Gi     9.5Gi
Swap:       2.0Gi        0      2.0Gi

Linux 需要交换空间吗?

建议为系统配置一定量的交换空间。虽然交换空间不是 Linux 系统的运行的必备条件,但它与充足的 RAM 一起,可以确保系统的性能和稳定性。

在 Ubuntu 系统中,默认会自动创建一个 2GB 的交换文件,这在一定程度上也表明了在 Linux 系统中使用交换空间的重要性,否则就没必要默认自动创建交换分区了。

机器的 RAM容量很大,还需要交换空间吗?

如果系统配置了 64GB 或更多的 内存,那么通常很难用完所有的 内存。因此,在这种情况下,交换空间的重要性降低,可以不必配置。

但在某些特殊情况下,仍然可能需要少量的交换空间以确保系统的稳定性。例如,如果某个故障程序占用了大部分 内存,交换空间可以帮助提高系统的稳定性。虽然这种情况不常见,但一旦发生,交换空间可以为系统提供额外的缓冲,从而避免崩溃。而且增加交换空间不会对系统造成任何损害,为什么不配置一点了?

Linux 中应该配置多少交换空间?

关于交换空间的大小,过去有一种普遍的说法是交换空间应为 RAM 大小的两倍,但在现代计算机中,这个规则已经不再适用。实际上,交换空间的大小并没有严格的指导原则。

根据 Red Hat 的建议,对于配备 4GB 或更大容量 RAM 的现代系统,交换空间的大小建议为 RAM 大小的 20%。

CentOS 的建议与 Red Hat 略有不同,具体如下:

  • 如果 机器的内存 小于 2GB,交换空间应为 RAM 大小的两倍。

  • 如果 机器的内存 超过 2GB,则交换空间应为 RAM 大小 + 2 GB(例如 3GB RAM 对应 5GB 交换空间)。

在 Ubuntu 中,交换空间的大小取决于是否使用休眠模式:

  • 如果需要休眠,交换空间应等于 RAM 大小。

  • 如果不需要休眠,建议如下:

    • 内存小于 1GB:交换空间应至少等于 RAM 大小,最多为其两倍。
    • 内存大于 1GB:交换空间应至少等于 RAM 大小的平方根,最多为其两倍。

交换空间如何工作?

引入交换空间后,涉及到交换分区的工作流程如下:

  1. 内存容量耗尽:当计算机的内存被完全使用完了,即没有足够的空间来处理新的任务时。
  2. 识别最近未访问的数据:操作系统会检查内存中的数据,找出那些最近没有被访问的数据。这些数据通常是暂时不需要的,可以安全地从内存中移出。
  3. 将数据从内存传输到交换空间:这些不活跃的数据会被移动到硬盘上的交换空间。这就像把书从桌子上移到书架上,以腾出空间让你继续在桌子上工作。
  4. 将新数据磁盘加载到内存:当新的任务需要内存或者之前移动的数据再次需要时,操作系统会将数据从交换空间移动回内存。

频繁交换导致的性能问题

在 物理内快满的情况下,可能会发生一种称为 "频繁交换"(thrashing) 的现象。这种现象通常会导致系统性能急剧下降,甚至使系统完全无响应。

当系统的物理内存几乎被完全占用,无法为新的或现有的进程提供足够的空间。

系统不断地将内存页移到交换空间,然后又从交换空间中取回。这种反复的页面切换占用了大量的 CPU 资源和 I/O 带宽,导致系统性能大幅下降变得极其缓慢,甚至无响应。

此时,如果使用 free 的命令来显示 CPU 负载和内存使用情况,你会发现 CPU 负载非常高,可能达到系统中 CPU 内核数量的 30 到 40 倍,并且内存和交换空间几乎完全被分配了。

sh 复制代码
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.7G        7.3G        100M        500M        300M        200M
Swap:          2.0G        1.9G        100M

如何在 Linux 中增加交换空间?

首先,您需要检查系统是否已经启用了交换空间。您可以在终端中输入以下命令来检查:

sh 复制代码
qin@linux-01:~$ sudo swapon --show
NAME      TYPE      SIZE USED PRIO
/dev/sda5 partition 2G   0B   -2

也可以使用free命令查看。

sh 复制代码
qin@linux-01:~$ free -h
              total     used     free      shared  buff/cache   available
Mem:        15Gi       4.7Gi    6.3Gi       986Mi     4.5Gi     9.5Gi
Swap:       2.0Gi        0      2.0Gi

可以看出,这里我的机器有 15 GB RAM,分配的交换空间内存为 2 GB。

1. 创建交换文件

首先,使用以下 dd 命令创建一个 1 GB 大小的交换文件:

sh 复制代码
sudo dd if=/dev/zero of=/swap_file bs=1GB count=1
2. 设置权限

为了确保交换文件的安全性,您需要将其权限设置为 600,防止其他用户读取其中的敏感数据:

sh 复制代码
sudo chmod 600 /swap_file
3. 在交换文件上启用交换区域

使用 mkswap 命令将该文件设置为交换区域:

sh 复制代码
sudo mkswap /swapfile
4. 在 fstab 文件中添加条目

为了确保每次系统重启后交换空间依然有效,需要将交换文件的信息添加到 fstab 文件中。可以使用以下 echo 命令来进行操作,或者手动编辑 fstab 文件:

sh 复制代码
echo "swap_file swap  swap  defaults  0 0" >> /etc/fstab
5. 扩展交换空间

要启用交换文件,请使用以下 swapon 命令:

sh 复制代码
sudo swapon /swap_file
6. 检查交换空间

使用以下命令来确认交换空间是否已启用:

sh 复制代码
free -m 

#或者
swapon -s

如果需要禁用交换文件,可以使用以下 swapoff 命令:

sh 复制代码
sudo swapoff /swap_file
相关推荐
乘风御浪云帆之上14 分钟前
数据库操作【JDBC & HIbernate & Mybatis】
数据库·mybatis·jdbc·hibernate
AAA.建材批发刘哥23 分钟前
Linux快速入门-Linux文件系统管理
linux·运维·服务器·c语言·学习方法
dazhong20122 小时前
PLSQL 客户端连接 Oracle 数据库配置
数据库·oracle
正在走向自律2 小时前
阿里云ESC服务器一次性全部迁移到另一个ESC
服务器·阿里云·云计算
gywl3 小时前
openEuler VM虚拟机操作(期末考试)
linux·服务器·网络·windows·http·centos
了一li4 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
日记跟新中4 小时前
Ubuntu20.04 修改root密码
linux·运维·服务器
唐小旭4 小时前
服务器建立-错误:pyenv环境建立后python版本不对
运维·服务器·python
码农君莫笑4 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio