首页 > 系统相关 >【转载】【内存】为什么手工drop_caches之后cache值并未减少?

【转载】【内存】为什么手工drop_caches之后cache值并未减少?

时间:2024-07-14 14:19:04浏览次数:8  
标签:cache drop free shared buffers caches

在Linux系统上查看内存使用状况最常用的命令是"free",其中buffers和cache通常被认为是可以回收的:

$ free

 total    used    free   shared  buffers   cached

Mem:   32764716  1067548  31697168   158332     12   593096

-/+ buffers/cache:   474440  32290276

Swap:   2103292     0  2103292

当内存紧张的时候,有一个常用的手段就是使用下面的命令来手工回收cache:

$ echo 1 > /proc/sys/vm/drop_caches

注:drop_caches接受以下三种值:

  • 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
    

当我们考虑有多少cache可供回收的时候,首先要知道的是:不同版本的"free"命令计算cache值的算法不同,据不完全统计举例如下:

  1. 版本:procps-3.2.8-36
    cache值等于/proc/meminfo中的Cached
  2. 版本:procps-3.3.9-10.1
    cache值等于/proc/meminfo[Cached + SReclaimable]
  3. 版本:procps-ng-3.3.10-3
    cache值等于/proc/meminfo[Cached + Slab]

注:

/proc/meminfo中的Cached表示page cache所占用的内存大小;

Slab表示内核Slab所占用的内存大小,slab有的可回收有的不可回收,其中可回收的通过SReclaimable表示,不可回收的通过SUnreclaim表示。

所以,对上述第2、3版本的"free"命令,echo 1 > /proc/sys/vm/drop_caches对其中的SReclaimableSlab部分是不起作用的。

即便仅考虑page cache (对应于 /proc/meminfoCached),也并不是所有的页面都可以回收的:

首先,drop_caches只回收clean pages,不回收dirty pages,参见https://www.kernel.org/doc/Documentation/sysctl/vm.txt

所以如果想回收更多的cache,应该在drop_caches之前先执行sync命令,把dirty pages变成clean pages

其次,即使提前执行了sync命令,drop_cache操作也不可能把cache值降到0,甚至有时候cache值几乎没有下降,这是为什么呢?因为page cache中包含的tmpfs和共享内存是不能通过drop_caches回收的。

Page cache用于缓存文件里的数据,不仅包括普通的磁盘文件,还包括了tmpfs文件,tmpfs文件系统是将一部分内存空间模拟成文件系统,由于背后并没有对应着磁盘,无法进行paging(换页),只能进行swapping(交换),在执行drop_cache操作的时候tmpfs对应的page cache并不会回收。

我们通过实验来观察tmpfs文件对free命令的影响:

挂载一个3G大小的tmpfs:

 $ mount -t tmpfs -o size=3G none /mytmpfs/

此时free命令看到的内存使用状况:

$ free

 ​       total    used    free   shared  buffers   cached

 Mem:   65942736  2343336  63599400    9492    8952   92848

 -/+ buffers/cache:  2241536  63701200 

 Swap:   33038332     0  33038332 

在tmpfs上新建一个2G大小的文件,free命令看到"cached"增加了2GB,注意"shared"也增加了2GB:

$ dd if=/dev/zero of=/mytmpfs/testfile bs=1G count=2

 2+0 records in

 2+0 records out

 2147483648 bytes (2.1 GB) copied, 2.42736 s, 885 MB/s

 $ free

 total    used    free   shared  buffers   cached

 Mem:   65942736  4423404  61519332  2106644    9088  2190064

 -/+ buffers/cache:  2224252  63718484 

 Swap:   33038332     0  33038332 

执行drop_caches,再观察free命令的"cached"值,发现刚才增加的2GB并未被回收:

 $ sync

 $ sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'

 $ free

 total    used    free   shared  buffers   cached

 Mem:   65942736  4430388  61512348  2106644    5284  2183096

 -/+ buffers/cache:  2242008  63700728 

 Swap:   33038332     0  33038332 

最后删除tmpfs上的文件,free命令看到"Cached"和"Shared"同时减少2GB:

 $ rm /mytmpfs/testfile

 $ free

total    used    free   shared  buffers   cached

 Mem:   65942736  2324096  63618640    9784    6228   87412

 -/+ buffers/cache:  2230456  63712280 

 Swap:   33038332     0  33038332 

结论:

tmpfs占用的page cache是不能通过drop_caches操作回收的,tmpfs占用的page cache同时也算进了shared中,也就是说,被视为共享内存。

Linux kernel利用tmpfs实现共享内存(shared memory),参见:

https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt

所以共享内存也和tmpfs一样,属于page cache,但又不能被drop_caches回收。这里所说的共享内存包括:

  • SysV shared memory
    是通过shmget申请的共享内存,用ipcs -mcat /proc/sysvipc/shm查看;
  • POSIX shared memory
    是通过shm_open申请的共享内存,用ls /dev/shm查看;
  • shared anonymous mmap
    通过mmap(…MAP_ANONYMOUS|MAP_SHARED…)申请的内存,可以用pmap -x或者cat /proc/<PID>/maps查看;*
    注:mmap调用参数如果不是MAP_ANONYMOUS|MAP_SHARED,则不属于tmpfs,比如MAP_ANONYMOUS|MAP_PRIVATE根本不属于page cache而是属于AnonPagesMAP_SHARED属于普通文件,对应的page cache可以回写硬盘并回收。*

我们通过一个实验来观察共享内存对free命令的影响。以下程序通过shared anonymous mmap方式申请256MB大小的内存:

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAP_SIZE 268435456

int main()

{

  char *addr;
  ssize_t s;
  addr = mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0);
  if (addr == MAP_FAILED) {

    fprintf(stderr, "mmap failed\n");

    exit(EXIT_FAILURE);

  }

  memset(addr, 9, MAP_SIZE);

  printf("mmap done, memset done, check free output. Press any key to exit...\n");
  getchar();
  exit(EXIT_SUCCESS);
}

实验过程如下:

先回收cache,设置初始状态:

$ sync; sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'; free

       total    used    free   shared  buffers   cached

Mem:   65942736  2401684  63541052    9576    3648   54820

-/+ buffers/cache:  2343216  63599520 

Swap:   33038332     0  33038332 

然后执行我们的测试程序,申请256MB共享内存:

$ ./mmap_test
mmap done, memset done, check free output. Press any key to exit...

在另一个窗口里观察,看到cache值增加了256MB,注意"shared"也同时增加了256MB:

$ free

 total    used    free   shared  buffers   cached

Mem:   65942736  2652796  63289940   271720    6380   321760

-/+ buffers/cache:  2324656  63618080 

Swap:   33038332     0  33038332 

执行drop_caches,发现刚才新增的256MBcache值并未被回收:

$ sync; sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'; free

	 total    used    free   shared  buffers   cached

Mem:   65942736  2666452  63276284   271720    3628   316532

-/+ buffers/cache:  2346292  63596444 

Swap:   33038332     0  33038332 

退出mmap_test程序,再看cache值就减少了256MB,注意"shared"也同时减少256MB:

$ free

	    total    used    free   shared  buffers   cached

Mem:   65942736  2400268  63542468    9576    4796   59148

-/+ buffers/cache:  2336324  63606412 

Swap:   33038332     0  33038332 

结论:cache值包含了共享内存的大小,然而drop_caches是不能回收它的。

总结:为什么drop_caches操作不能回收所有的page cache?

  • dirty pages不能回收;
  • 共享内存和tmpfs不能回收(注意观察free命令显示的shared值);
  • 不同版本的free命令有不同的计算cache值的方法,有的包含了slabSReclaimableecho 1 > /proc/sys/vm/drop_caches是不能回收slab的,echo 3 > /proc/sys/vm/drop_caches也只是回收slab中的SReclaimable部分。

原文链接:https://mp.weixin.qq.com/s?__biz=MzAxOTk3OTgxOQ==&mid=2247483661&idx=1&sn=b53d42adb2b80c756c5ad51b637ea252 如有侵权,请联系作者删除!

标签:cache,drop,free,shared,buffers,caches
From: https://www.cnblogs.com/dongxb/p/18301499

相关文章

  • 缓存框架-Spring Cache基本用法
    一、概述SpringCache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。SpringCache提供了一层抽象,底层可以切换不同的缓存实现,例如:EHCacheCaffeineRedis(常用)二、环境准备1、导入Redis和SpringCache依赖<dependency><groupId......
  • 接口文档的书写,git的拉取错误的解决,数据库多表查询的进一步认识(以后开发一定要先仔细
    202407111接口文档的书写:1.1首先写你这个大模块是什么功能。1.2开始根据你的功能写接口文档:2解决git拉取错误的问题:2.1出现这样的问题:(推送出错)2.2原因分析:可能因为重装过系统,或者是安装git的位置发生了变化等情况出现。2.3找到git的安装路径,打开gitbash之后,进......
  • 13--memcache与redis
    前言:数据库读取速度较慢一直是无法解决的问题,大型网站应对的方式主要是使用缓存服务器来缓解这种情况,减少数据库访问次数,以提高动态Web等应用的速度、提高可扩展性。1、简介Memcached/redis是高性能的分布式内存缓存服务器,通过缓存数据库查询结果,减少数据库访问次数,以提高动......
  • Memcached介绍和详解
    Memcached介绍和详解Memcached是一个高性能的分布式内存对象缓存系统,通过在内存中缓存数据来减少数据库的读取次数,从而提高动态Web应用程序的速度和效率。下面将详细介绍Memcached的安装、配置和使用方法。Memcached简介Memcached是一个基于内存的缓存系统,它通常用于缓......
  • and-design-vue设置dropdownClassName无效的问题
    样式发现是有插入的,但是没有生效,使用:deep也一样没有效果问题来源改组件是根app同级,所以使用:deep无效解决办法使用:global,需要加“!important”......
  • 21、Django-缓存(强缓存和协商缓存)-@cache-page()装饰器
    定义:缓存是一类可以更快的读取数据的介质的统称、也指其它可以加快数据读取的存储方式、一般用来存储临时数据、常用介质的是读取速度很快的内存意义:视图渲染有一定的成本、数据库的频繁查询过高、所以对于低频变动的页面可以考虑使用缓存技术、减少实际渲染的次数、用户拿到相......
  • [CISCN2019 华北赛区 Day1 Web1]Dropbox
    进入题目注册一个账号登录进去后上传一个文件发现只能上传图片下载删除时分别抓包发现在download.php里下载,在delete.php处删除发现filename参数,有任意文件下载漏洞下载download.php,delete.php目录遍历在delete.php里发现class.phpdb=$db;}publi......
  • 【总线】AXI4第七课时:AXI的额外的控制信息(PROT和CACHE)
             大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计感兴趣,那你绝对不能错过我们今天的主角——AXI4总线。作为ARM公司AMBA总线家族中的佼佼者,AXI4以其高性能和高度可扩展性,成为了现代电子系统中不可或缺的通信桥梁。    上......
  • GuavaCache、EVCache、Tair、Aerospike 缓存框架比较
    GuavaCache、EVCache、Tair、Aerospike是不同类型的缓存解决方案,它们各有特点和应用场景。下面我会逐一分析这些缓存系统的优势、应用场景,并提供一些基本的代码示例。GuavaCache优势特点:内置在Guava库中,易于集成和使用。提供了丰富的缓存配置选项,如过期策略、缓存加载策略......
  • 解锁Memcached的Key长度极限:深入探索与实践
    ......