彻底理解 linux 的内存回收

news2024/10/7 2:25:03

本文试图用最浅显的语言说明以下问题:

1、free 命令中的buffer/cache 是什么意思?

2、内存回收的机制是什么?

3、内存回收的门限是什么?也就是什么时候进行回收?

4、如何手动清除cache?

1、free 命令中的buffer/cache 是什么意思?

当我们的系统长时间运行一段时间后,执行 free 命令,会发现 buff/cache 占用的内存非常大,这里的 buffer/cache 到底是什么呢?又为什么会变得这么大呢?被它占用内存还能被其它进程正常使用吗?其实buff/cache 是指buffer cache 和 page cache,这里对这两个概念解释一下:

Page Cache

page cache 以page为单位,缓存文件内容。缓存在page cache中的文件数据,能够更快的被用户读取。同时对于带buffer的写入操作,数据在写入到page cache中即可立即返回,而不需等待数据被实际写到到磁盘,进而提高了上层应用读写文件的整体性能。

Buffer Cache

磁盘的最小数据单位为sector,每次读写磁盘都是以sector为单位对磁盘进行操作。

sector大小跟具体的磁盘类型有关,有的为512Byte, 有的为4K Bytes。无论用户是希望读取1个byte,还是10个byte,最终访问磁盘时,都必须以sector为单位读取,如果裸读磁盘,那意味着数据读取的效率会非常低。

同样,如果用户希望向磁盘某个位置写入(更新)1个byte的数据,他也必须整个刷新一个sector,言下之意,则是在写入这1个byte之前,我们需要先将该1byte所在的磁盘sector数据全部读出来,在内存中,修改对应的这1个byte数据,然后再将整个修改后的sector数据,一口气写入磁盘。

为了降低这类低效访问,尽可能的提升磁盘访问性能,内核会在磁盘sector上构建一层缓存,他以sector的整数倍力度单位(block),缓存部分sector数据在内存中,当有数据读取请求时,他能够直接从内存中将对应数据读出。当有数据写入时,他可以直接再内存中直接更新指定部分的数据,然后再通过异步方式,把更新后的数据写回到对应磁盘的sector中。这层缓存则是块缓存Buffer Cache。

从上面解释可以看出:Page Cache和Buffer Cache是一个事物的两种表现:对于一个Page而言,对上,它是某个File的一个Page Cache,而对下,它同样是一个磁盘Device上的一组Buffer Cache

这两种cache 在最早的内核中,是独立存在的,但在Linux-2.4以后,这两种cache已经融合到一起了,融合后的Buffer Cache不再以独立的形式存在,Buffer Cache的内容,直接存在于Page Cache中。关于buffer cache 和 page cache的发展进程,感兴趣的可以参考文章 [1]。

既然我们理解的这个概念,在linux系统中,只要我们打开过的文件,文件的内容和元数据信息都会存在 page cache中,随着打开的文件越来越多,page cache 的占用就会越来越大,这也就是为什么我们看到的 buff/cache 会非常大的原因,其实这是正常的,这是linux内核为了提高访问磁盘的性能而做的一种优化。

那被buff/cache占用的内存还可以被其它进程使用吗?答案是不可以的。随着buff/cache占用的内存越来越大,等大到一定的程度,内核会触发内存回收的线程来回收这些page,被回收后的page才可以被其它进程使用。

2、内存回收的对象、回收机制和门限

2.1 内存回收的对象

内存回收是linux内核发现内存已经不够用的时候去出动回收内存的一种机制,那回收的对象是谁呢?可能是 file-backed pages  , 也可能是 swap 的内存 ,到底先回收哪一个呢,天平应该往那一边倾斜呢,这个在linux 里面是通过 swapiness这个参数来设置的。swapiness 是内存回收的其中1个参数 : 反应是否积极的使用swap 空间。如果回收的对象是 file-backed pages,就是 将内存中的page cache 都丢弃了,下次再用的时候,从disk中再都回来。

默认值:

$ cat /proc/sys/vm/swappiness 
60
 

内存不足:free and file-backed pages < high water mark in a zone

swappiness=0   表示仅在内存不足的情况下,使用swap空间

swappiness=60  默认值

swappiness=100  内核将积极的使用swap空间

2.2 内存回收的机制

内存回收的机制可以下面一张图来理解: 

 内核给内存设置了三个水位:

  • min_free_kbytes
  • low_free_kbytes
  • high_free_kbytes

如果此时前台有个进程APP,在疯狂的申请内存,每次申请2G,然后写内存,如上图所示,此时系统内存会逐渐减少,当达到如下水位:

high_free_kbytes  该水位是回收的目标,是保证空闲内存在 high水位以上,空闲内存达到high 水位以后,kswapd就会 stop relcaim。

low_free_kbytes 当系统内存减少到该水位,kswapd启动 reclaim,但是如果前台APP还是在疯狂的申请内存,而kswapd回收的速度比较慢,系统的空闲内存会继续减少,可能达到 min水位。

min_free_kbytes 系统剩余的最小可用的内存,当系统内存减少到该水位,还有进程线程在疯狂的要内存,如果系统回收的速度达不到不索取内存的速度,系统会直接阻塞你的前台进程或者线程,这个时候你会发现程序执行的很慢,这个过程在Linux 中的属于叫 direct reclaim

min_free_kbytes 就是系统无论如何都要保证的可用内存,那是不是所以的线程都无法使用该水位一下的内存呢?答案是否定的,

因为 Linux 里面是有一些情况是要使用 紧急内存的,比如 回收内存的代码,它也是需要内存的啊,它在申请内存的时候,会加上一个 PF_MEMALLOC 的标志,

带上这个标志之后,就可以不受 min 水位的限制,使用min水位一下的内存。

2.3 内存水位计算

本文基于linux4.19内核来说明

min_free_kbytes 的默认值:

min_free_kbytes 会随着内存的增大而增大,但不是线性的增大,根据代码mm/page_alloc.c里的说明:

 这里的lowmem_kbytes 根据代码里是系统各个内存zone受管理的page之和,也就是系统内存的大小,在我的平台上 NXP-LS1046A ARM64平台上,16GB的内存大小:

 那根据代码里的说明,我系统的 min_free_kbytes 大概在 16149Kbytes 左右,但是我系统里的值:

root@dddd:~# cat /proc/sys/vm/min_free_kbytes 
45056

 而且系统里没有做其它设置

 

 看了下代码才确定 内核使能了 CONFIG_TRANSPARENT_HUGEPAGE

$ cat mm/Makefile | grep hugepa
obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o khugepaged.o

经过确认是 mm/hugepaged.c 中 set_recommended_min_free_kbytes进行的设置,具体设置的根据核方法,可以参考该函数,这里暂不做具体讲解。

watermark[min] = per_zone_min_free_pages

watermark[high] - watermark[low]

                = watermark[low] - watermark[min] 

                = per_zone_min_free_pages * 1/4

3 如何手动清除cache?

参考 Documentation/sysctl/vm.txt

drop_caches

Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes.  Once dropped, their
memory becomes free.

To free pagecache:
        echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
        echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
        echo 3 > /proc/sys/vm/drop_caches

Refer: 

[1]. buffer cache与page cache

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/663246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【高危】Apache NiFi H2驱动存在代码注入漏洞

漏洞描述 Apache NiFi 是一个开源的数据流处理和自动化工具&#xff0c;DBCPConnectionPool 和 HikariCPConnectionPool 是两个控制器服务&#xff0c;用于提供对数据库的连接池管理功能。 Apache NiFi 受影响版本&#xff0c;由于 DBCPConnectionPool 和 HikariCPConnectio…

景点景区门票购买核销宴会活动报名公众号系统开发

景点景区门票购买核销宴会活动报名公众号系统开发 功能特性 1.活动管理 可以新建一场或多场活动&#xff0c;管理每一场活动&#xff1b;与此同时&#xff0c;可以添加多张收费或免费门票&#xff0c;满足特定的需求&#xff1b;填写举办城市后&#xff0c;客户可通过定位服务&…

Vue + Axios全局接口防抖、节流封装实现,让你前端开发更高效

你是否有过这样的经历&#xff0c;每当你在前端开发中使用 Ajax 进行数据请求时&#xff0c;往往因为一些错误操作导致页面不断地发送请求&#xff0c;甚至导致了系统崩溃&#xff1f;为了解决这个问题&#xff0c;我们需要对接口进行防抖和节流处理。 本文将介绍如何使用 Vue …

Windows BAT脚本指令总结和笔记

最近在工作的项目工程中遇到了各式各样的bat脚本&#xff0c;故总结和记录下所遇到的指令&#xff1b; 文章目录 1 echo off2 REF3 SET4 %~dp05 %~nx06 CALL7 pushd8 rmdir 1 echo off echo off的意思是在批处理运行命令的时候不会一条一条的显示执行的命令&#xff0c;与之相…

香港Web3欲戴王冠,银行如何承受合规之重?

前言 6月19日&#xff0c;据明报报道&#xff0c;香港金融管理局&#xff08;HKMA&#xff09;总裁余伟文针对虚拟资产交易平台在香港银行开户难问题表示&#xff0c;一向有与香港银行有交流&#xff0c;“交流时是否有压力则大家感觉不一”。上周四&#xff0c;HKMA向汇丰银行…

vulhub-struts2-S2-005 远程代码执行漏洞复现

漏洞描述 s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12)&#xff0c;struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象&#xff0c;struts框架通过过滤#字符防止安全问题&#xff0c;然而通过unicode编码(…

优维低代码实践:面包屑配置以及菜单配置

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

Pyinstaller打包Sklearn(即scikit-learn)+Pyqt5代码报错,程序无法正常运行

前言 在网上看了大部分解决办法都不能解决我的问题&#xff0c;后面自己摸索之后&#xff0c;解决问题&#xff0c;记录如下。 提供一篇大佬文章&#xff0c;一般能解决大部分问题&#xff1a; https://blog.csdn.net/u012219045/article/details/115397646 建议先看我的文章…

Java复习0619

关键字: static Static&#xff1a;静态的&#xff0c;随着类的加载而加载、执行。static用来修饰: 属性、方法、代码块、内部类熟悉: static修饰的类变量、类方法与不使用static修饰的区别。 类变量: 类的生命周期内&#xff0c;只有一个。被类的多个实例共享。 掌握: 我们遇…

企业备份和恢复软件推荐

数据备份是在发生灾难或事故时通过将数据从一个位置复制到另一个位置来保护数据的过程。数据是任何组织的生命线&#xff0c;丢失数据会导致严重损坏并中断业务运营。96% 的用户至少经历过数据丢失的主要原因之一&#xff1a;人为错误、硬盘驱动器故障、断电、火灾和自然灾害。…

ES(Elasticsearch)和Kibana(Windows)安装

安装Elasticsearch和Kibana 安装Elasticsearch过程 首先需要到官网下载安装包 注意&#xff1a;要下载对应的版本&#xff0c;如果下载最新版而且jdk是1.8版本的话&#xff0c;会出现warning: ignoring JAVA_HOMEC:\Program Files\Java\jdk1.8.0_191; using bundled JDK这样…

Git本地仓库使用

说明&#xff1a;Git是版本控制和协同开发的工具 下载Git 第一步&#xff1a;下载 在官网&#xff08;https://git-scm.com/download/win&#xff09;&#xff0c;选择自己的版本自行下载 第二步&#xff1a;安装 下载下来后&#xff0c;使用默认设置&#xff0c;不要改动任…

Redis6之配置文件与发布订阅

配置文件 ################################### NETWORK ############################## # 指定 redis 只接收来自于该IP地址的请求&#xff0c;如果不进行设置&#xff0c;那么将处理所有请求 bind 127.0.0.1#是否开启保护模式&#xff0c;默认开启。要是配置里没有指定b…

Java和bean(VO)、dao、Servlet、jsp的综合总结复习

学到这里&#xff0c;差不多&#xff0c;可以自主完成一个简单的系统了。所以接下来需要总结&#xff0c;然后设计一个简单的系统。分别使用Java和Java Web来实现。&#xff08;目标&#xff1a;实现简单的购物系统&#xff09; 要求&#xff1a;能注册&#xff0c;并登录。登…

【python】四舍五入保留N位小数,截断保留小数

目录 一.环境 二.适用场景 三.具体方法代码及描述 1.方法一&#xff1a;numpy-around()方法&#xff0c;四舍五入 2.方法二&#xff1a;字符串格式化&#xff08;有两种方式&#xff0c;均为四舍五入&#xff09;【推荐】 1&#xff09;%.4f 法 2) {:.4f} 法 3.方法三…

QT入门基础知识

什么是QT QT是一个跨平台的C图像用户界面应用程序框架QT在1991年由奇趣科技开发QT的优点 跨平台,几乎支持所有平台接口简单&#xff0c;容易上手一定程度上简化了内存回收机制有很好的社区氛围可以进行嵌入式开发 QWidget QT注意事项 命名规范 类名 首字母大写&#xff0c;单…

kakfa 常见错误(长期更新)

kafka版本 2.13-3.40 一、消费者相关1.1 消费组1.1.1 查看消费组命令找不到消费组 1.2 主题1.2.1 kafka默认主题_consumer_offsets 不小心删除 二、发布者相关三、Spring Boot连接相关3.1 消费者相关3.1.1 连接报错3.1.1.2 消费报错 一、消费者相关 1.1 消费组 1.1.1 查看消费…

vue中Cascader 级联选择器实现

<template> <div style"padding-left:20px;"> <!-- 添加或修改 --> <el-dialog :title"title" :visible.sync"open" width"500px" append-to-body> <el-form ref"form" :model"form"…

二分类结局变量Logistic回归临床模型预测—— 模型评价(二)

本节讲的是二分类结局变量的临床模型预测,与之前讲的Cox回归不同,https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/1240…

如何运行一个 SSM 项目以及解决 JDBC 连接数据库遇到的问题(已解决)

文章目录 &#x1f4cb;前言&#x1f3af;运行与配置&#x1f3af;报错与解决&#x1f9e9;问题分析&#x1f9e9;解决过程 &#x1f3af;知识点补充&#x1f9e9;关于 com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别 &#x1f4dd;最后 &#x1f4cb;前言 这篇文…