什么是swap?
swap space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合。简单点说,当系统物理内存吃紧时,Linux会将内存中不常访问的数据保存到swap上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问swap上存储的内容时,再将swap上的数据加载到内存中,这就是我们常说的swap out和swap in。
swap何用之有?
一些大型应用在启用时调用的内存其实在使用时很少用,这时候一直占用物理内存就会浪费,用swap后系统会把不常用的数据先放swap,以便更多的物理内存用于cache,从而提高系统整体性能。
什么是cache?
cache,其作用是为了更好的利用局部性原理,减少CPU访问主存的次数。简单地说,CPU正在访问的指令和数据,其可能会被以后多次访问到,或者是该指令和数据附近的内存区域,也可能会被多次访问。因此,第一次访问这一块区域时,将其复制到cache中,以后访问该区域的指令或者数据时,就不用再从主存中取出。
到底有必要配置swap吗?
如果物理内存宽裕的情况下,谨慎配置,因为物理内存的速度和交换内存的级别是差了好几个档次的
如果物理内存勉强够的情况下,建议配置,因为万一发生内存爆炸的情况,可以用swap缓解争取我们的处理时间
如果物理内存不够用的情况下,不建议配置,因为配置了也只是勉强能用,没有性能可言,最好还是加物理内存
如果没有配置swap会如何?
如果物理内存够用的话没有任何影响,就算是内存使用异常也能设置报警有充足的时间处理
如果本身内存紧张,内存使用异常,当内存被用光的时候,没有配置swap,内核的OOM killer被触发,可能连保存工作进度的机会都没有。
什么是OOM killer?
1.检查文件/proc/sys/vm/panic_on_oom,如果里面的值为2,那么系统一定会触发panic
2.如果/proc/sys/vm/panic_on_oom的值为1,那么系统有可能触发panic
3.如果/proc/sys/vm/panic_on_oom的值为0,或者上一步没有触发panic,那么内核继续检查文件/proc/sys/vm/oom_kill_allocating_task
3.如果/proc/sys/vm/oom_kill_allocating_task为1,那么内核将kill掉当前申请内存的进程
4.如果/proc/sys/vm/oom_kill_allocating_task为0,内核将检查每个进程的分数,分数最高的进程将被kill
进程被kill掉之后,如果/proc/sys/vm/oom_dump_tasks为1,且系统的rlimit中设置了core文件大小,将会由/proc/sys/kernel/core_pattern里面指定的程序生成core dump文件,这个文件里将包含
pid, uid, tgid, vm size, rss, nr_ptes, nr_pmds, swapents, oom_score_adj
score, name等内容,拿到这个core文件之后,可以做一些分析,看为什么这个进程被选中kill掉。
如何建立swap
Linux下有两种类型的swap空间,swap分区和swap文件,他们有各自的特点:
- swap分区上面由于没有文件系统,所以相当于内核直接访问连续的磁盘空间,效率相对要高点,但由于swap分区一般安装系统时就分配好了了,后期要缩减空间和扩容都很不方便。
- swap文件放在指定分区的文件系统里面,所以有可能受文件系统性能的影响,但据说2.6版本以后的内核可以直接访问swap文件对应的物理磁盘地址,相当于跳过了文件系统直接访问磁盘,不过如果swap文件在磁盘上的物理位置不连续时,还是会对性能产生不利影响,但其优点就是灵活,随时可以增加和移除swap文件。
添加swap分区
在添加swap分区前,首先得有一个空闲的分区,如果是一块新的磁盘,可以用fdisk来创建一个新的分区用于swap。
#创建swap分区
dev@dev:~$ sudo mkswap /dev/sdb1
Setting up swapspace version 1, size = 2 GiB (2146430976 bytes)
no label, UUID=d69621de-618a-4bea-9a96-b8e8b0d0ea40
#查看系统中现在正在使用的swap,以便于和添加后做比较
dev@dev:~$ swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -1
#将新的分区加入到系统中
dev@dev:~$ sudo swapon /dev/sdb1
#这时候可以看到新的swap分区已经被加入到系统中了,并且优先级比原来的要低
dev@dev:~$ swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -1
/dev/sdb1 partition 2096124 0 -2
#为了保证系统重启后会自动加载我们新的swap分区,需要修改/etc/fstab文件
dev@dev:~$ sudo sh -c 'echo "/dev/sdb1 none swap sw 0 0" >> /etc/fstab'
#查看一下,确保写入成功,这里的第一条是原来的系统的swap分区,第二条是我们刚添加的
dev@dev:~$ grep swap /etc/fstab
/dev/mapper/dev--vg-swap_1 none swap sw 0 0
/dev/sdb1 none swap sw 0 0
添加swap文件
#先创建一个新的512M的文件,用来作为swap文件,文件路径可以随便
#fallocate这个命令依赖于文件系统,有些老的文件系统不支持这个命令,比如ext2,
#这种情况下可以用dd来实现同样的效果:
#sudo dd if=/dev/zero of=/mnt/512MiB.swap bs=1024 count=524288
#fallocate和dd的区别在于:
#fallocate是先声明这么多,然后在具体用到的时候文件系统才分配真正的物理磁盘空间,就是用一点分配一点,
#而dd是一开始就实实在在的写了512m的数据到物理磁盘空间。
#所以作为测试来说fallocate方便些,因为刚开始不用写任何数据,要快
dev@dev:~$ sudo fallocate -l 512m /mnt/512MiB.swap
#修改文件的权限,避免其他用户对这个文件进行误操作
dev@dev:~$ sudo chmod 600 /mnt/512MiB.swap
#格式化为swap文件
dev@dev:~$ sudo mkswap /mnt/512MiB.swap
#将新的文件加入到系统中
dev@dev:~$ sudo swapon /mnt/512MiB.swap
#这时候可以看到新的swap文件已经被加入到系统中了,类型为file
#这里可以看到由于优先级最高,第一个swap分区/dev/dm-1已经被使用了24K
dev@dev:~$ swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 24 -1
/dev/sdb1 partition 2096124 0 -2
/mnt/512MiB.swap file 524284 0 -3
#从free命令的输出可以看到,经过前面两轮添加swap分区和文件,
#现在系统的交换空间已经变成3G(3144692K)了
dev@dev:~$ free
total used free shared buff/cache available
Mem: 500192 39112 9564 1996 451516 430820
Swap: 3144692 24 3144668
#同样为了保证系统重启后会自动加载我们新的swap文件,需要修改/etc/fstab文件
dev@dev:~$ sudo sh -c 'echo "/mnt/512MiB.swap none swap sw 0 0" >> /etc/fstab'
注意:不是所有的文件系统都支持创建swap文件,如btrfs,在btrfs分区里创建swap文件将失败。
取消swap
#停掉所有系统正在使用的swap
dev@dev:~$ sudo swapoff -a
#swapon -s命令没有任何输出,free命令显示swap空间为0,说明swapoff成功
dev@dev:~$ swapon -s
dev@dev:~$ free
total used free shared buff/cache available
Mem: 500192 35924 348888 2004 115380 433924
Swap: 0 0 0
#当然我们还需要修改/etc/fstab,否则下次重启后,系统又会重新挂载相应的swap分区和文件
#使用自己喜欢的编辑器,将/etc/fstab中跟swap相关的三行删掉即可(本例中是三行,请根据实际情况调整)