免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 2078 | 回复: 0

为什么手工DROP_CACHES之后CACHE值并未减少? [复制链接]

论坛徽章:
140
2015年亚洲杯之日本
日期:2015-04-28 13:32:012015年亚洲杯之朝鲜
日期:2015-05-06 10:16:442015年亚洲杯之日本
日期:2015-05-06 10:21:342015年亚洲杯纪念徽章
日期:2015-05-13 17:16:442015亚冠之北京国安
日期:2015-05-13 17:18:292015亚冠之鹿岛鹿角
日期:2015-05-13 17:19:062015亚冠之德黑兰石油
日期:2015-05-27 16:47:402015亚冠之塔什干棉农
日期:2015-05-28 15:24:122015亚冠之卡尔希纳萨夫
日期:2015-06-01 13:52:392015亚冠之柏斯波利斯
日期:2015-06-04 17:37:292015亚冠之阿尔纳斯尔
日期:2015-06-16 11:31:202015亚冠之塔什干火车头
日期:2015-06-23 10:12:33
发表于 2018-08-06 10:44 |显示全部楼层
在Linux系统上查看内存使用状况最常用的命令是”free”,其中buffers和cache通常被认为是可以回收的:
  1. $ free
  2.              total       used       free     shared    buffers     cached
  3. Mem:      32764716    1067548   31697168     158332         12     593096
  4. -/+ buffers/cache:     474440   32290276
  5. Swap:      2103292          0    2103292
复制代码

当内存紧张的时候,有一个常用的手段就是使用下面的命令来手工回收cache:
  1. $ 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值的算法不同,据不完全统计举例如下:
  • 版本:procps-3.2.8-36
    cache值等于/proc/meminfo中的”Cached”;
  • 版本:procps-3.3.9-10.1
    cache值等于/proc/meminfo的 [Cached + SReclaimable];
  • 版本: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”对其中的SReclaimable或Slab部分是不起作用的。
即便仅考虑page cache (对应于 /proc/meminfo 的”Cached”),也并不是所有的页面都可以回收的:
首先,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命令的影响:
  1. 挂载一个3G大小的tmpfs:
  2. $ mount -t tmpfs -o size=3G none /mytmpfs/

  3. 此时free命令看到的内存使用状况:
  4. $ free
  5.              total       used       free     shared    buffers     cached
  6. Mem:      65942736    2343336   63599400       9492       8952      92848
  7. -/+ buffers/cache:    2241536   63701200
  8. Swap:     33038332          0   33038332

  9. 在tmpfs上新建一个2G大小的文件,free命令看到"cached"增加了2GB,注意"shared"也增加了2GB:
  10. $ dd if=/dev/zero of=/mytmpfs/testfile bs=1G count=2
  11. 2+0 records in
  12. 2+0 records out
  13. 2147483648 bytes (2.1 GB) copied, 2.42736 s, 885 MB/s
  14. $ free
  15.              total       used       free     shared    buffers     cached
  16. Mem:      65942736    4423404   61519332    2106644       9088    2190064
  17. -/+ buffers/cache:    2224252   63718484
  18. Swap:     33038332          0   33038332

  19. 执行drop_caches,再观察free命令的"cached"值,发现刚才增加的2GB并未被回收:
  20. $ sync
  21. $ sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'
  22. $ free
  23.              total       used       free     shared    buffers     cached
  24. Mem:      65942736    4430388   61512348    2106644       5284    2183096
  25. -/+ buffers/cache:    2242008   63700728
  26. Swap:     33038332          0   33038332

  27. 最后删除tmpfs上的文件,free命令看到"Cached"和"Shared"同时减少2GB:
  28. $ rm /mytmpfs/testfile
  29. $ free
  30.              total       used       free     shared    buffers     cached
  31. Mem:      65942736    2324096   63618640       9784       6228      87412
  32. -/+ buffers/cache:    2230456   63712280
  33. 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 -m”或”cat /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而是属于AnonPages,MAP_SHARED属于普通文件,对应的page cache可以回写硬盘并回收。

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


  1. #include <sys/mman.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>

  7. #define MAP_SIZE 268435456

  8. int main()
  9. {
  10.     char *addr;
  11.     ssize_t s;

  12.     addr = mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0);
  13.     if (addr == MAP_FAILED) {
  14.         fprintf(stderr, "mmap failed\n");
  15.         exit(EXIT_FAILURE);
  16.     }
  17.     memset(addr, 9, MAP_SIZE);

  18.     printf("mmap done, memset done, check free output. Press any key to exit...\n");
  19.     getchar();
  20.     exit(EXIT_SUCCESS);
  21. }
复制代码
实验过程如下:
  1. 先回收cache,设置初始状态:
  2. $ sync; sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'; free
  3.              total       used       free     shared    buffers     cached
  4. Mem:      65942736    2401684   63541052       9576       3648      54820
  5. -/+ buffers/cache:    2343216   63599520
  6. Swap:     33038332          0   33038332

  7. 然后执行我们的测试程序,申请256MB共享内存:
  8. $ ./mmap_test
  9. mmap done, memset done, check free output. Press any key to exit...

  10. 在另一个窗口里观察,看到cache值增加了256MB,注意"shared"也同时增加了256MB:
  11. $ free
  12.              total       used       free     shared    buffers     cached
  13. Mem:      65942736    2652796   63289940     271720       6380     321760
  14. -/+ buffers/cache:    2324656   63618080
  15. Swap:     33038332          0   33038332

  16. 执行drop_caches,发现刚才新增的256MBcache值并未被回收:
  17. $ sync; sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'; free
  18.              total       used       free     shared    buffers     cached
  19. Mem:      65942736    2666452   63276284     271720       3628     316532
  20. -/+ buffers/cache:    2346292   63596444
  21. Swap:     33038332          0   33038332

  22. 退出mmap_test程序,再看cache值就减少了256MB,注意"shared"也同时减少256MB:
  23. $ free
  24.              total       used       free     shared    buffers     cached
  25. Mem:      65942736    2400268   63542468       9576       4796      59148
  26. -/+ buffers/cache:    2336324   63606412
  27. Swap:     33038332          0   33038332
复制代码

结论:cache值包含了共享内存的大小,然而drop_caches是不能回收它的。
注:上例是shared anonymous mmap,如果是SysV shared memory或POSIX shared memory,结果是一样的。

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

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

转自:http://linuxperf.com/?p=201




您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP