内存管理
Swap
swap可以避免应用程序因内存不足而崩溃,但它的性能远不及内存,适用于特殊场景(例如我的ecs只有2G内存😅)。实现方式可以基于交换文件,也可以基于磁盘分区,并且内核参数vm.swappiness可以定义swap与内存的使用占比,即优先使用内存还是swap。
创建一个交换文件作为Swap
# 创建一个交换文件作为Swap
dd if=/dev/zero of=/swapfile bs=1M count=4096
# 设置合适的权限
chmod 600 /swapfile
# 将文件格式化为swap空间
mkswap /swapfile
# 启用swap文件
swapon /swapfile
# 持久化
echo '/swapfile none swap sw 0 0' >> /etc/fstab
# 检查Swap是否已启用
free -h
swapon --show使用磁盘分区作为Swap
如果你想将整个磁盘分区作为swap,而不是使用交换文件,可以按照以下步骤进行:
- 创建swap分区(可以使用
fdisk或parted工具):
- 使用
fdisk创建一个新的Linux swap分区,通常选择类型为82(Linux swap)。
- 格式化该分区为swap格式:
sudo mkswap /dev/sdXn # 替换 /dev/sdXn 为你刚刚创建的分区- 启用swap分区:
sudo swapon /dev/sdXn- 确保分区在启动时自动启用:
修改
/etc/fstab文件,添加如下内容:
/dev/sdXn none swap sw 0 0Swap相关内核参数
vm.swappiness是Linux内核中用来控制交换的行为的参数。它的值决定了内存满时交换的优先级。值的范围是0到100,0表示内存几乎用完之前不会交换,100表示内存稍微紧张时就会使用swap。
查看当前swappiness值:
cat /proc/sys/vm/swappiness临时调整swappiness:
sudo sysctl vm.swappiness=30 # 设置为30,降低交换的频率永久更改swappiness:
编辑/etc/sysctl.conf文件,加入:
vm.swappiness=30然后执行:
sudo sysctl -p—
buffer
-
Buffers 是内核缓冲区用到的内存
-
对应的是 /proc/meminfo 中的 Buffers 值。
-
# cat /proc/meminfo ... Buffers: 2104 kB ...
-
-
Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样,内核就可以把分散的写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。合并这里似乎和大数据生态中的Hadoop组件中的小文件合并有相似。
-
缓冲区,数据写入磁盘前暂时存放的空间
cache
-
Cache 是内核页缓存和 Slab 用到的内存
-
对应的是 /proc/meminfo 中的 Cached 与 SReclaimable 之和。
-
# cat /proc/meminfo |grep SReclaimable ... Cached: 1079152 kB ... SReclaimable: 125492 kB ...
-
-
Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。
-
缓存区,将磁盘中的内容暂时读入到cache中可以提高效率
范例:
[root@8 ~]# free -h
total used free shared buff/cache available
Mem: 941Mi 174Mi 580Mi 6.0Mi 186Mi 620Mi
Swap: 0B 0B 0B
[root@8 ~]# dd if=/dev/sda of=/dev/null bs=300M
#buff/cache明显增加
[root@8 ~]# free -h
total used free shared buff/cache available
Mem: 941Mi 169Mi 365Mi 6.0Mi 405Mi 623Mi
Swap: 0B 0B 0B清除buff/cache
- 生产中不要使用,因为buff/cache是可以提高效率的,并且改成3后将改不回默认值0了 除非重启
- 帮助:man proc
[root@centos8 ~]#echo 3 > /proc/sys/vm/drop_caches
[root@centos8 ~]#free -h
total used free shared buff/cache available
Mem: 1.8Gi 320Mi 1.3Gi 9.0Mi 152Mi 1.3Gi
Swap: 2.0Gi 0B 2.0Gibuff & cache 总结
-
为了提高文件的写入效率,在现代的操作系统中,当用户调用 write 函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正的将缓冲区中的数据写入到磁盘里。
-
这种做法虽然提高了效率,但是也为写入数据带来了安全问题,因为如果计算机发生停机,那么保存在内存缓冲区里的写入数据将会丢失。
-
为此,系统提供了 fsync 和 fdatafync 两个同步函数,它们可以强制让操作系统立即将缓冲区的数据写入到磁盘里面,从而确保写入数据的安全性。
-
好比你在 window 系统打开一个 word 文档,当你写一些内容时就相当于写入,但是你写的内容并没有真正的保存,而是放在一个缓冲区,如果这时关闭的话内容就会丢失。只有当你点击保存时内容才真正的保存(同步)到磁盘,点击保存就好比调用同步函数 fsync 和 fdatafync。
buff & cache 相关工具
free # 查看内存使用量 以及内存中buff/cache的使用量
sync # 将缓冲区的数据写入到持久存储中内存寻址范围
寻址范围计算公式:内存容量(MB)*8 / 字长(按字编址)
-
若某台小米笔记本Air 13.3中字长为64位,内存容量为12GB,按字编址,则这台小米笔记本可寻址范 围为(1536M ) 1GB =1024MB 故寻址范围 = 12*1024*8 / 64 = 12*128 =1536M
—
SWAP
- **buffer:**缓冲区(数据写入磁盘前 临时存放的空间)
- **cache:**缓存(将磁盘的数据导入到内存中 提高数据的访问速度)
swap 概述
- 临时利用磁盘顶替内存空间(避免因内存不足而导致程序执行失败),但性能较差,因为磁盘的性能远不及内存
- 生产中通常禁用swap
swap 相关内核参数
-
/proc/sys/vm/swappiness 的值决定了当内存占用达到一定百分比时,会启用swap分区空间
-
范例:
[root@aliyun ~]# cat /proc/sys/vm/swappiness
30
#临时修改此值
[root@aliyun ~]# echo 0 > /proc/sys/vm/swappiness- **说明:**内存在使用到100-30=70%的时候,就开始使用swap空间。简单说这个值就是定义了swap的使用倾向,默认值为30,值越大表示越倾向于使用swap。可以设为0,0表示最大限度的减少使用swap,而不是不使用swap。
swap 相关命令
查看swap:
-
swapon -s(本质上就查看:cat /proc/swaps)
-
# 如果配置有多个swap分区或者文件的话,这里将会有多行,每行代表一个正在被系统使用的swap分区或文件 dev@dev:~$ swapon -s Filename Type Size Used Priority /dev/dm-1 partition 524284 0 -1 Filename # 如果swap类型是分区,这里将是分区的路径,如果swap类型是文件,这里将是文件的路径 Type # swap的类型,partition代表这是一个swap分区,file代表这是一个swap文件 Size # swap的大小,单位是k,这里524284表示的差不多是512M Used # 已经被使用的大小,这里0表示还没有被使用到 Priority # 优先级,优先级高的swap将会被优先使用,同等优先级的swap将会被均匀的使用(round-robin算法),优先级可以通过“swapon -p”命令来设置
-
-
free -h
-
top
临时禁用swap:
- swapoff /dev/sdc1
创建swap文件系统:
- mkswap
同步swap:
- swapon -a(创建swap后不会立即生效,需要创建swap文件系统后进行同步)
swap 的效率对比
- 整块硬盘的swap > 基于分区的swap > 基于文件的swap
- 基于分区的swap 靠前的分区要比靠后的分区速度快,但仅限于普通磁盘,因为分区考前就表示磁道也靠外,普通磁盘读取数据是从磁道外到内读取的
swap 创建
基于分区创建 swap
- 注意:磁盘分区操作一定要小心,弄不好就会造成数据丢失、系统挂掉的后果。
# 创建swap分区
# fdisk /dev/
...
Last sector, +sectors or +size{K,M,G,T,P} (169873408-209715199, default 209715199): +2G #添加一个2G的分区
Command (m for help): t # 修改文件系统类型
Partition number (1-5, default 5): 5
...
Hex code (type L to list all codes): 82 # 82表示swap分区
...
Command (m for help): p
...
/dev/sda5 169873408 174067711 4194304 2G 82 Linux swap / Solaris
Command (m for help): w # 存盘退出
# 创建文件系统
# mkswap /dev/sda5
# 查看创建文件系统后的swap
# lsblk -f /dev/sda5
NAME FSTYPE LABEL UUID MOUNTPOINT
sda5 swap 548ed2f6-e829-4489-b2ae-471c623c858b
# blkid /dev/sda5
/dev/sda5: UUID="548ed2f6-e829-4489-b2ae-471c623c858b" TYPE="swap" PARTUUID="c0a5b2de-05"
# 挂载
# vim /etc/fstab
...
UUID=548ed2f6-e829-4489-b2ae-471c623c858b swap swap defaults 0 0
# 同步swap
# swapon -a
# 查看创建的swap
# free -h
total used free shared buff/cache available
Mem: 941Mi 190Mi 587Mi 6.0Mi 163Mi 604Mi
Swap: 2.0Gi 0B 2.0Gi
# swapon -s
Filename Type Size Used Priority
/dev/sda5 partition 2097148 0 -2
# cat /proc/swaps
Filename Type Size Used Priority
/dev/sda5 partition 2097148 0 -2基于文件 swap
- 注意:不是所有的文件系统都支持创建swap文件,如btrfs,在btrfs分区里创建swap文件将失败。
# 创建swap文件
# dd if=/dev/zero of=/data/swapfile bs=1M count=1024
# 将文件权限改为600,否则创建时会报错
# chmod 600 /data/swapfile
# 创建文件系统
# mkswap /data/swapfile
# 挂载
# vim /etc/fstab
...
/data/swapfile swap swap defaults 0 0
# 同步swap
# swapon -a
# 查看创建的swap
# free -h
total used free shared buff/cache available
Mem: 941Mi 195Mi 60Mi 3.0Mi 685Mi 602Mi
Swap: 3.0Gi 4.0Mi 3.0Gi
# swapon -s
Filename Type Size Used Priority
/dev/sda5 partition 2097148 4364 -2
/data/swapfile file 1048572 0 -3基于磁盘创建 swap
- 通常不这么做,因为使用整块硬盘空间来创建swap太大了
swap 优先级
- 优先级数值越高 则越优先使用此swap设备
# 提升swap的优先级
pri=number # 使用fstab文件挂载时在defaults处修改
# 然后可以使用swapon -s查看swap 禁用
# 停掉所有系统正在使用的swap
# swapoff -a
#swapon -s命令没有任何输出,free命令显示swap空间为0,说明swapoff成功
# swapon -s
# 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相关的三行删掉即可(本例中是三行,请根据实际情况调整)swap 范例
#未启用swap
# free -h
total used free shared buff/cache available
Mem: 941Mi 204Mi 365Mi 18Mi 371Mi 562Mi
Swap: 0B 0B 0B
#600M的文件可以创建
# dd if=/dev/zero of=file.img bs=600M count=1
# ll -h file.img
-rw-r--r-- 1 root root 600M Apr 5 10:45 file.img
#800M的文件就已经提示进程被kill掉了,其实就是内存不足所导致
# dd if=/dev/zero of=file2.img bs=800M count=1
Killed
# ll -h file2.img
-rw-r--r-- 1 root root 0 Apr 5 10:47 file2.img
#添加swap
#再次测试查看系统中swap in/out的情况
并不是swap空间占用多就一定性能下降,真正影响性能是swap in和out的频率,频率越高,对系统的性能影响越大,我们可以通过vmstat命令来查看swap in/out的频率
如果swap容量固定不变,那内存就不是瓶颈。可以用vmstat 1命令看,si so两列的数值在不断变化时,内存就不够了。
# 参数2表示每两秒统计一次,si和so两列就是每秒swap in和out的次数
dev@ubuntu:~$ vmstat 2
procs------------memory--------------swap----io-----system-----------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 70232 75620 7940 209476 0 0 0 0 111 180 0 1 99 0 0
0 0 70232 75620 7940 209476 0 0 0 0 116 186 1 1 99 0 0
0 0 70228 75620 7940 209476 2 0 2 0 120 193 1 1 98 1 0
0 0 70228 75620 7940 209476 0 0 0 0 117 186 0 0 100 0 0
0 0 70228 75620 7940 209476 0 0 0 0 113 184 0 1 99 0 0