Linux 性能分析总结之内存缓存与Swap(四)

Buffer/Cache 与 Swap 作用

0x00 前言

在简单的了解了内存的基本原理和如何查看内存的命令free -h后,还要需要了解内存的一些参数含义。如下所示,基本上所有的参数看名字就知道是啥意思,但是有这几个看名字可能也不知道具体是干啥的,所以还需要深入了解下。

  • shared 共享内存
  • buff/cache 缓存
  • Swap 交换内存
~ # free -h

total used free shared buff/cache available

Mem: 1.8Gi 177Mi 1.1Gi 8.0Mi 479Mi 1.4Gi

Swap: 4.0Gi 0B 4.0Gi

shared 内存是所有被 tmpfs 文件系统使用的内存和共享内存,用于和其他进程共同使用的内存(进程间通信)和加载的动态链接库和程序的代码段.我对 shared 内存的也没有更深入的了解,但我觉得像动态库和程序的代码段这些都是”死“的东西,不需要频繁的分配和回收,所以一般情况下不会造成内存的性能问题,所以这里就不细说了,那么剩下的 buff/cache 和 swap 由于会比较频繁的分配和回收,所以得详细说说。

在详细说之前,首先要弄明白以下两个问题,那么就很容易理解这篇笔记的思路了。

  1. 为什么需要内存?

    简而言之就是计算机各个部件的速度不匹配,可以查看下面这个计算机金字塔图,而解耦速度不一致的神器就是缓存,上到消息队列,下到 CPU 寄存器,无一不是这个道理,所以可以知道内存是作为磁盘的缓存。

mem_pyramid.jpeg

  1. 我们所说的内存性能问题是什么?

    缓存是有大小限制的,要是无限大那我们所有东西都放缓存里就得了。自然内存也是有大小限制了,那么我们平时常说的内存性能问题则主要指内存容量的问题和缓存命中率的问题。

当我们弄明白了上面这两个问题,又可以延伸出这些问题,这也是本篇笔记要讲的重点。

  1. 内存页分类
  2. 内存容量不足怎么换入换出

好,接下来我们带着这些问题来深究

0x10 Buffer/Cache

  1. Buffer 和 Cache 分别是干嘛的?

    我们可以执行 man free命令查看说明文档,Buffer 和 Cache 是用作磁盘 I/O 的缓存。磁盘作为一个块设备,上面会有文件系统,我们可以暂时把文件系统理解为对块设备的抽象和封装,而存储在块设备上的文件都是由文件系统来组织和管理。而对磁盘的读写有两种,一种是经过文件系统,还有一种是不经过文件系统,也就是直接读写块设备。由此对应,Buffer 是对块设备读写的缓存,而 Cache 则是对文件系统读写的缓存。

  2. 由于文件系统是在块设备之上,那么文件系统的缓存是不是在 Cache 和 Buffer 里都有一份?

    早期的Linux会的,也就是cache两次。不过现在不会了,只会经过一层cache。实际上 Buffer 和 Cache 可以比喻成一个数据结构一致的数组,只不过块设备的缓存放一部分,文件系统的缓存放另一部分。

  3. 内存页中有哪些页?

  • 文件页
  • 文件映射页
  • 文件匿名页
  1. Buffer 和 Cache 是怎么回收的?

    Buffer 和 Cache 都是可以被回收的,而这些被叫做File-backed page(文件页)。被程序修改过的还没写入磁盘的叫做脏页,所以如果要回收先要把脏页写到磁盘里。方式有:

    • 应用程序中调用: fsync
    • 内核线程: pdflush

0x20 Swap

上面说了文件页的回收,匿名页是怎么回收的呢?这就是 Linux 的 swap 机制,把不常用的内存里不常用的匿名页放在 Swap 里面,也是就是磁盘里面,然后空出地方来给别的进程用。所以 Swap 就需要:

  • 换出,把暂时不用的数据存到磁盘里
  • 换入,当进程再次访问这些内存的时候,把他们从磁盘读到内存里。
  1. 内存回收的方式?

    • 直接内存回收: buffer 和 cache
    • 定期内存回收:kswapd0内核线程
  2. 定期回收内存的 watermark
    image.png

    • 剩余 < 阈值: 只有内核可以分配
    • page_min < 剩余 < page_low: kswapd0 回收内存
    • page_low < 剩余 < page_hight: 有压力
    • 剩余 > page_high: 没压力

0x21 NUMA

NUMA 全称叫(Non-Uniform Memory Access)。就是多核心的处理器划到不同的 Node,每个 Node 都有自己的内存空间。当要内存回收时,可能是从其他 Node寻找空闲内存,或者从本 Node 回收。有时候发现内存空间很足,但仍然换出了内存到 swap 里面就是这个原因。

0x22 Swappiness

调节回收匿名页和文件页的权重

0x30 总结

  1. 为什么需要内存:各元件速度不匹配
  2. buff 和 cache:对应块设备和文件系统
  3. 内存页类型:文件页和匿名页分别对应缓存和 swap 内存
  4. 回收方式:分别对应直接回收和定期回收
  5. Swap 下的 NUMA 架构和调节 Swappniness