首先说明 , 本文讨论的cache指的是linux中的page cache , buffer指的是buffer cache , 也即cat /proc/meminfo中显示的cache和buffer 。
我们知道 , Linux下频繁存取文件或单个大文件时物理内存会很快被用光 , 当程序结束后内存不会被正常释放而是一直作为cahce占着内存 。因此系统经常会因为这点导致OOM产生 , 尤其在等大压力场景下概率较高 , 此时 , 第一时间查看cache和buffer内存是非常高的 。此类问题目前尚未有一个很好的解决方案 , 以往遇到大多会做规避处理 , 因此本案尝试给出一个分析和解决的思路 。
解决该问题的关键是理解什么是cache和buffer , 什么时候消耗在哪里以及如何控制cache和buffer , 所以本问主要围绕这几点展开 。整个讨论过程尽量先从内核源码分析入手 , 然后提炼App相关接口并进行实际操作验证 , 最后总结给出应用程序的编程建议 。
可以通过free或者cat /proc/meminfo查看到系统的buffer和cache情况
文章插图
free命令的全解析
1.1 Cache和Buffer分析从cat /proc/meminfo入手 , 先看看该接口的实现:
static int meminfo_proc_show(struct seq_file *m, void *v){……cached = global_page_state(NR_FILE_PAGES) - total_swapcache_pages() - i.bufferram;if (cached < 0) cached = 0;…… seq_printf(m, "MemTotal: %8lu kBn" "MemFree: %8lu kBn" "Buffers: %8lu kBn" "Cached: %8lu kBn" …… , K(i.totalram), K(i.freeram), K(i.bufferram), K(cached), …… );……}其中 , 内核中以页框为单位 , 通过宏K转化成以KB为单位输出 。这些值是通过si_meminfo来获取的:
void si_meminfo(struct sysinfo *val){ val->totalram = totalram_pages; val->sharedram = 0; val->freeram = global_page_state(NR_FREE_PAGES); val->bufferram = nr_blockdev_pages(); val->totalhigh = totalhigh_pages; val->freehigh = nr_free_highpages(); val->mem_unit = PAGE_SIZE;}其中bufferram来自于nr_blockdev_pages() , 该函数计算块设备使用的页框数 , 遍历所有块设备 , 将使用的页框数相加 。而不包含普通文件使用的页框数 。
long nr_blockdev_pages(void){ struct block_device *bdev; long ret = 0; spin_lock(&bdev_lock); list_for_each_entry(bdev, &all_bdevs, bd_list) { ret += bdev->bd_inode->i_mapping->nrpages; } spin_unlock(&bdev_lock); return ret;}从以上得出meminfo中cache和buffer的来源:
- Buffer就是块设备占用的页框数量;
- Cache的大小为内核总的page cache减去swap cache和块设备占用的页框数量 , 实际上cache即为普通文件的占用的page cache 。
这里,我们使用cp命令拷贝一个50MB的文件操作,内存会发生什么变化:
[root nfs_dir] # ll -h file_50MB.bin-rw-rw-r-- 1 4104 4106 50.0M Feb 24 2016 file_50MB.bin[root nfs_dir] # cat /proc/meminfoMemTotal: 90532 kBMemFree: 65696 kBBuffers: 0 kBCached: 8148 kB……[root@test nfs_dir] # cp file_50MB.bin /[root@test nfs_dir] # cat /proc/meminfoMemTotal: 90532 kBMemFree: 13012 kBBuffers: 0 kBCached: 60488 kB可以看到cp命令前后 , MemFree从65696 kB减少为13012 kB , Cached从8148 kB增大为60488 kB , 而Buffers却不变 。那么过一段时间 , Linux会自动释放掉所用的cache内存吗?一个小时后查看proc/meminfo显示cache仍然没有变化 。
推荐阅读
- 活的化石,昌宁的千年古茶树
- 教你如何把电脑磁盘标修改成你女神的图片
- win10网页出现stack overflow at line 0的解决方法
- 太平猴魁外形品质的审评方法介绍
- 不知道这十项Linux常识,别说自己是运维工程师
- 普洱茶消费主流不是快消品
- HTTPS原理看了很多,这个是最清晰的
- MySQL中的并发控制概览
- 获取有关 Linux shell 内置命令的帮助
- SEO竞争对手分析