Linux下频繁读写文件,导致可用内存减少

 

问题现象:

Linux下从服务器下载文件时,通过回调函数一直写文件,频繁的进行write操作,导致系统可用内存一直减少,有时候可能会导致程序执行因为内存问题异常。

测试代码如下:

/******************************************************************
 *   Copyright (C) 2019 All rights reserved.
 *   
 *   File  Name :memory_test.c
 *   The  Author:Wang
 *   Create Date:2019年08月20日
 *   Discription:
 *
 *   Update Log :
 *
 *****************************************************************/
#include

#define SIZE (1024 * 1024)

int main (int  argc, const char  *argv[])
{
	int i = 0;
	int wrote_byte = 0;
	char buffer[SIZE] = {0};

	printf("open file : %s\n", argv[1]);
	FILE *fp = fopen(argv[1], "ab");
	if (NULL == fp) {
		printf("open file failed\n");
		return -1;
	}

	for (i = 0; i < SIZE; i++) {
		buffer[i] = i;     
	}

	while (1) {
		wrote_byte = fwrite(buffer, SIZE, 1, fp);
		printf("wrote size : %d\n", SIZE * 1);
		if (wrote_byte != 1) {
			printf("write failed.\n");
			return -1;
		}

		usleep(500000);
	}

	fclose(fp);
	return 0;
}

运行程序以及通过free命令的现象如下:
不断向文件写数据:

Linux下频繁读写文件,导致可用内存减少_第1张图片

free命令查看系统内存使用情况,free可用的内存一直减少,但是buff/cache部分一直增加:
Linux下频繁读写文件,导致可用内存减少_第2张图片

问题分析:

先看些free命令的参数解释:

total 内存总数

used 已经使用的内存数

free 空闲的内存数

shared 多个进程共享的内存总额

buff/cache Buffer Cache和cached Page Cache 磁盘缓存的大小

available 可用的内存

其中free部分是可用的内存,buff/cache部分是磁盘缓存的大小。关于其中buff/cache的描述 “为了提高磁盘存取效率, Linux做了一些精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换), 还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。”,关于这部分的介绍网上有很多的介绍资料,所以上述例子在运行的时候,free的内存一直减少,buff/cache的内存一直增加。

问题解决方法:

一般Linux系统在内存快要消耗完的时候,会触发内存回收的操作,会自动释放一些内存,也就是说会从buff/cache中释放缓存。如果因为这个问题导致程序执行失败的情况,也可以手动进行释放缓存,通过对/proc/sys/vm/drop_caches文件进行操作可以释放缓存。

@ubuntu:$ cat /proc/sys/vm/drop_caches 
0
//默认值是0

往上关于这个文件的介绍如下(该部分介绍转自:http://www.idcyunwei.org/post/162.html)

echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。
echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)
echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的缓存对象。

所以解决上述例子中问题可以定期执行以下的命令:

sync   //落盘处理,保证文件的正确性
echo 3 > /proc/sys/vm/drop_caches   //表示清除pagecache和slab分配器中的缓存对象

执行后现象如下图,free部分内存增加了很多,buff/cache部分内存减少了很多:
Linux下频繁读写文件,导致可用内存减少_第3张图片

你可能感兴趣的:(linux)