Linux buffer/cache介绍

2023-05-16

free 命令 与 buffer/cache

在 Linux 系统中,我们经常用 free -m命令来查看系统内存的使用状态:
在这里插入图片描述
-m: 显示单位为MB
free -m 各个参数的说明
total 内存总数
used 已经使用的内存数
free 空闲的内存数
shared 多个进程共享的内存总额
buff/cache 缓存的大小
available 可用内存 free + buff/cache

什么是 buffer/cache?

buffer 和 cache 是两个在计算机技术中被用滥的名词,放在不同语境下会有不同的意义。在 Linux 的内存管理中,这里的buffer 指 Linux 内存的:Buffer cache。这里的 cache 指 Linux 内存中的:Page cache。翻译成中文可以叫做缓冲区缓存和页面缓存。在历史上,它们一个(buffer)被用来当成对 io 设备写的缓存,而另一个(cache)被用来当作对 io 设备的读缓存,这里的 io 设备,主要指的是块设备文件和文件系统上的普通文件。但是现在,它们的意义已经不一样了。在当前的内核中,page cache 顾名思义就是针对内存页的缓存,说白了就是,如果有内存是以 page 进行分配管理的,都可以使用 page cache 作为其缓存来管理使用。当然,不是所有的内存都是以页page进行管理的,也有很多是针对块block进行管理的,这部分内存使用如果要用到 cache 功能,则都集中到 buffer cache 中来使用。(从这个角度出发,是不是 buffer cache 改名叫做 block cache 更好?)然而,也不是所有块block都有固定长度,系统上块的长度主要是根据所使用的块设备决定的,而页长度在 X86 上无论是32位还是64位都是 4k。

明白了这两套缓存系统的区别,就可以理解它们究竟都可以用来做什么了。

什么是 page cache

Page cache 主要用来作为文件系统上的文件数据的缓存来用,尤其是针对当进程对文件有 read/write 操作的时候。如果你仔细想想的话,作为可以映射文件到内存的系统调用:mmap 是不是很自然的也应该用到 page cache?在当前的系统实现里, page cache 也被作为其它文件类型的缓存设备来用,所以事实上 page cache 也负责了大部分的块设备文件的缓存工作。

什么是 buffer cache

Buffer cache 则主要是设计用来在系统对块设备进行读写的时候,对块进行数据缓存的系统来使用。这意味着某些对块的操作会使用 buffer cache 进行缓存,比如我们在格式化文件系统的时候。一般情况下两个缓存系统是一起配合使用的,比如当我们对一个文件进行写操作的时候,page cache 的内容会被改变,而 buffer cache 则可以用来将 page 标记为不同的缓冲区,并记录是哪一个缓冲区被修改了。这样,内核在后续执行脏数据的回写writeback时,就不用将整个 page 写回,而只需要写回修改的部分即可。

如何回收 cache?

Linux 内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。一般情况下,这个操作中主要的内存释放都来自于对 buffer/cache 的释放。尤其是被使用更多的 cache 空间。既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放 cache,作为 free 空间分给相关进程使用。所以一般情况下,我们认为 buffer/cache 空间可以被释放,这个理解是正确的。

但是这种清缓存的工作也并不是没有成本。理解 cache 是干什么的就可以明白清缓存必须保证 cache 中的数据跟对应文件中的数据一致,才能对 cache 进行释放。所以伴随着 cache 清除的行为的,一般都是系统 IO 飙高。因为内核要对比 cache 中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收。

在系统中除了内存将被耗尽的时候可以清缓存以外,我们还可以使用/proc/sys/vm/drop_caches这个文件来人工触发缓存清除的操作。

buff/cache不断增长?

可以看到,上图的cache已经飙升到113.9G,而free剩余内存只有3.77G左右,并且随着系统的运行该值会越来越大,那为什么buff/cache会越来越大?

Linux服务器运行一段时间后,由于其内存管理机制,会将暂时不用的内存转为buff/cache,这样在程序使用到这一部分数据时,能够很快的取出,从而提高系统的运行效率,所以这也正是linux内存管理中非常出色的一点,所以乍一看内存剩余的非常少,但是在程序真正需要内存空间时,linux会将缓存让出给程序使用,这样达到对内存的最充分利用,所以真正剩余的内存是free+buff/cache

但是有些时候大量的缓存占据空间,这时候应用程序会去使用swap交换空间,从而使系统变慢,这时候需要手动去释放内存。

说到清理内存,那么不得不提到/proc这一个虚拟文件系统,这里面的数据和文件都是内存中的实时数据,很多参数的获取都可以从下面相应的文件中得到,比如查看某一进程占用的内存大小和各项参数,cpu和主板的详细信息,显卡的参数等等;相应的关于内存的管理方式是在/proc/sys/vm/drop_chches文件中,一定要注意这个文件中存放的并不是具体的内存内容,而是0-3这几个数字,通过文件大小只有1B也可以知道,而这些代号分别告诉系统代表不同的含义如下:

0:是系统默认值,默认情况下表示不释放内存,由操作系统自动管理
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存

所以根据上面的说明,分别将1,2,3这3个数字重定向到drop_caches中可以实现内存的释放,一般释放内存都是重定向3到文件中,释放所有的缓存。

buff/cache 缓存释放

只释放页缓存
1、 free -m 查看当前内存剩余

在这里插入图片描述
当前内存剩余3.8G左右,另外buff/cache是114G,根据上面说的现在真正的剩余内存应该是18G左右。

2、首先写缓存到文件系统:

sync

3、释放内存(页缓存buff/cache):

echo 1 > /proc/sys/vm/drop_caches

4、到这里内存就释放完了,现在drop_caches中的值为1,如果现在想让操作系统重新分配内存,那么设置drop_caches的值为0即可:

echo 0 > /proc/sys/vm/drop_caches

另外需要注意的是,在生产环境中的服务器我们不要频繁的去释放内存,只在必要时候清理内存即可,更重要的是我们应该从应用程序层面去优化内存的利用和释放,经常清理内存可能只是暂时屏蔽的应用程序中的一些bug,所以更重要的是程序的调优,其他的交给操作系统来管理。

总结

Buffer 可以用作将数据写入磁盘的缓存,也可以用作输出从磁盘读取的缓存
Cache 可以用作文件读取数据的页缓存,也可用作写文件作页的缓存

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux buffer/cache介绍 的相关文章

  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • Linux shell 脚本中的 while 循环超时

    这工作正常 无限循环 while TRUE do printf done 我在尝试着timeout this while loop与timeout命令 所有这些都不起作用 timeout 5 while TRUE do printf don
  • 归档文件系统或格式

    我正在寻找一种文件类型来存储已退役系统的档案 目前 我们主要使用 tar gz 但从 200GB tar gz 存档中查找并提取几个文件是很麻烦的 因为 tar gz 不支持任何类型的随机访问读取规定 在你明白之前 使用 FUSE 安装 t
  • 在 Linux 中禁用历史记录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 要在 Linux 环境中禁用历史记录 我执行了以下命令 export HISTFILESIZE 0 export HISTSIZE 0 u
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • 修改linux下的路径

    虽然我认为我已经接近 Linux 专业人士 但显然我仍然是一个初学者 当我登录服务器时 我需要使用最新版本的R 统计软件 R 安装在 2 个地方 当我运行以下命令时 which R I get usr bin R 进而 R version
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 跟踪 Linux 程序中活跃使用的内存

    我想跟踪各种程序在特定状态下接触了多少内存 例如 假设我有一个图形程序 最小化时 它可能会使用更少的内存 因为它不会重新绘制窗口 这需要读取图像和字体并执行大量库函数 这些对象仍然可以在内存中访问 但实际上并没有被使用 类似的工具top它们
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • GLIBCXX_3.4.26 未找到在 BeagleBone 上运行交叉编译的程序

    我有以下程序 include
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 应用程序无缘无故地被杀死。怀疑 BSS 高。如何调试呢?

    我已经在CentOs6 6中成功运行我的应用程序 最近 硬件 主板和内存 更新了 我的应用程序现在毫无理由地被杀死 root localhost PktBlaster PktBlaster Killed 文件和 ldd 输出 root lo
  • 如何根据 HTTP 请求使用 Python 和 Flask 执行 shell 命令并流输出?

    下列的这个帖子 https stackoverflow com questions 15092961 how to continuously display python output in a webpage 我能够tail f网页的日志
  • 如何在 shell 脚本中并行运行多个实例以提高时间效率[重复]

    这个问题在这里已经有答案了 我正在使用 shell 脚本 它读取 16000 行的输入文件 运行该脚本需要8个多小时 我需要减少它 所以我将其划分为 8 个实例并读取数据 其中我使用 for 循环迭代 8 个文件 并在其中使用 while
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c

随机推荐

  • java什么是monitor和Monitor监视器锁、对象布局

    文章目录 Monitor监视器锁什么是moniter对象布局 Monitor监视器锁 每个同步对象都有一个自己的Monitor 监视器锁 xff0c 加锁过程如下图所示 xff1a 任何一个对象都有一个Monitor与之关联 xff0c 当
  • proto的介绍和基础使用

    内容摘抄自书籍 Netty redis zookeeper高并发实战 Protobuf使用 proto文件来预先定义的消息格式 数据包是按照proto文件所定义的消息格式完成二进制码流的编码和解码 proto文件 xff0c 简单地说 xf
  • springboot使用oshi获取系统cpu、内存、jvm信息

    OSHI 是基于 JNA 的 xff08 本地 xff09 操作系统和硬件信息库 它不需要安装任何其他额外的本地库 xff0c 旨在提供一种跨平台的实现来检索系统信息 xff0c 例如操作系统版本 进程 内存和 CPU 使用率 磁盘和分区
  • 常用的linux命令

    目录相关命令 xff1a ls 列出当前目录下的文件列表信息 目录 文件夹 当前 xff1a 登陆成功之后 xff0c 打开终端所处的一个目录 a 显示隐藏文件 linux下以 开头的文件是隐藏文件 xff0c 默认不显示 l 显示目录下文
  • 字节后端一二面,讯飞一面

    1 自我介绍 2 rdb aof 3 线程池 4 ping命令用了什么协议 5 应用层的协议 6 为什么四次挥手要timewait 7 算法题 xff1a 和为k的子数组个数 xff08 前缀和 xff09 8 幻读 7 隔离级别 8 tc
  • mysql以某个字段分组进行条件查询,如果为0则补0

    需求 xff1a 有一个version plan表 xff0c 其中有一个字段is urgent 且每个version plan与一个模块moduleId关联 xff0c 现在要查出is urgent为1的模块数和这个模块的总数 xff0c
  • 数据库系统第六章-关系数据理论复习

    候选码若关系中的一个属性或属性组的值能够唯一地标识一个元组 xff0c 且他的子集不能唯一的标识一个元组 xff0c 则称这个属性或属性组做候选码 函数依赖 范式 虽然STC xff08 S T C xff09 3NF xff0c 但它仍存
  • Spring Security登录验证过程详解

    前端 xff1a 在前端页面输入username和password 通过地址login访问验证 后台 xff1a 调用 AbstractAuthenticationProcessingFilter doFilter 方法 原因 xff1a
  • 关于STL的一些理解

    1 集合set 定义 xff1a set lt int gt s1 类型可选 se begin 返回指向第一个元素的迭代器 se clear 清除所有元素 常用 se count 返回某个值元素的个数 常用 xff0c 一般用来查这个元素在
  • ModuleNotFoundError: No module named ‘...’:报错解决方案

    1 module包没安装 这个 就是包的名字 xff0c 看问题定位 xff0c import源文件 xff0c 然后去site packages里找那个模块 xff0c 如果是空的没安装 xff0c 这时候可以在对应的环境里使用pip i
  • C语言----结构体,枚举,共用体

    1 xff09 结构体 span class token comment 例 xff1a 一个描述学生的结构体 span span class token keyword struct span span class token class
  • Nvidia jetson agx xavier can通讯失败,修改时钟源pllaon

    一 问题详情 在调试Xavier can的过程中 xff0c can通信始终有问题 xff0c 收发都会报错 后来发现时钟源导致波特率不匹配 xff0c 所以不能通信 二 修改时钟源 在虚拟机使用官方sdkmanager xff0c 下载安
  • linux下实现https访问

    http转https 适用于linux服务器 linux下nginx 43 ssl实现https访问 xff08 一 xff09 环境准备 xff08 二 xff09 下载nginx源码 xff0c 编译nginx并添加ssl模块 xff0
  • Nvidia Jetson nano 安装Archiconda、gpu版torch、踩坑记录

    Nvidia Jetson nano 安装Archiconda gpu版torch 踩坑记录 jetson nano 属于aarch64架构 xff0c 不同于一般的x86 64的linux系统架构 xff0c 而torch官网上面 htt
  • linux下的yum,vim,gcc,gdb

    我们在windows系统下我们能够很简单进行粘贴复制下载安装 xff0c 也能通过vs进行我们缩写代码的编译运行 xff0c 但是我们在linux下我们应该怎样去操作我们的这些命令呢 xff0c 这章我们就讲解一下我们linux下常用的一些
  • 【Keil】Keil5添加源程序和头文件

    xxx c就是源程序 xxx h就是头文件 源程序添加方法 双击文件夹 xff0c 例如图片上的Source xff0c 跳出弹窗 xff0c 选择需要添加的源程序即可 添加头文件的方法 1 首先点击图片红框处 xff0c 或是在文件夹te
  • C 标准库 string常用函数 笔记

    文章目录 64 TOC 文章目录 前言字符串长度strlen sizeof 字符串拼接strcat strncat 字符串拷贝strcpy strncpy memcpy 内存填充memset 字符串比较strcmp strncmp 字符串查
  • node.js中的http.request方法使用说明_node.js

    方法说明 xff1a 函数的功能室作为客户端向HTTP服务器发起请求 语法 xff1a 复制代码 代码如下 http get options callback 由于该方法属于http模块 xff0c 使用前需要引入http模块 xff08
  • ARM中SP、LR、PC三个寄存器介绍

    寄存器定义和用途 定义 寄存器是中央处理器内的组成部份 寄存器是有限存贮容量的高速存贮部件 xff0c 它们可用来暂存指令 数据和位址 用途 可将寄存器内的数据执行算术及逻辑运算 xff1b 存于寄存器内的地址可用来指向内存的某个位置 xf
  • Linux buffer/cache介绍

    free 命令 与 buffer cache 在 Linux 系统中 xff0c 我们经常用 free m命令来查看系统内存的使用状态 xff1a m 显示单位为MB free m 各个参数的说明 total 内存总数 used 已经使用的