Page 1 of 1

【分享】用户态管理buffer 和cache 的方法

Posted: 2022年 Dec 19日 19:23
by shanjm

[toc]

嵌入式产品对内存的使用比较敏感,如果高效的控制和使用内存,能够有效的减少硬件内存的大小,同时提高系统的流畅行,这里简单介绍一下用户态管理控制内存 buffer和cache 的方法。

使用posix_fadvise控制 page Cache

Linux访问文件时会对对应文件进行缓冲,posix fadvise 用于释放对应文件的 对应地址的缓冲 。

Code: Select all

 int posix_fadvise(int fd, off_t offset, off_t len, int advice);
 
fd: 文件名
offset: 文件中的偏移量
len: 长度
advice: 
    POSIX_FADV_NORMAL: 表示该应用程序没有建议提供有关其指定的数据访问模式。如果没有意见,给出了一个打开的文件,这是默认的假设。
    POSIX_FADV_SEQUENTIAL:该应用程序需要访问指定的数据顺序(与以前高的人读低偏移)。
    POSIX_FADV_RANDOM:将指定的数据将会以随机顺序进行访问。
    POSIX_FADV_NOREUSE: 将指定的数据将只访问一次
    POSIX_FADV_WILLNEED: 将指定的数据将在不久的将来访问
    POSIX_FADV_DONTNEED: 指定的数据不会在短期内被访问

返回值: 
 0: 成功
 EBADF:  The *fd* argument was not a valid file descriptor.
 EINVAL:   An invalid value was specified for *advice*.
 ESPIPE:    The specified file descriptor refers to a pipe or FIFO. (Linux actually returns EINVAL in this case.)

建议: 在打开的文件某段地址的数据不再使用时,释放该段内存可以使用

Code: Select all

fsync(fd);
posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);

使用vmtouch控制Cache

vmtouch是一个可移植的文件系统cahce诊断和控制工具,下载地址https://github.com/hoytech/vmtouch.git 可以进行交叉编码,放入rootfs.

vmtouch 用途:

  1. 查看一个文件(或者目录)哪些部分在内存中;
  2. 把文件调入内存;
  3. 把文件清除出内存,即释放page cache;
  4. 把文件锁住在内存中而不被换出到磁盘上;

其使用方法可参考其help:

Code: Select all

Usage: vmtouch [OPTIONS] ... FILES OR DIRECTORIES ...
Options:
-t touch pages into memory
-e evict pages from memory
-l lock pages in physical memory with mlock(2)
-L lock pages in physical memory with mlockall(2)
-d daemon mode
-m max file size to touch
-p use the specified portion instead of the entire file
-f follow symbolic links
-h also count hardlinked copies
-w wait until all pages are locked (only useful together with -d)
-v verbose
-q quiet=

使用 BLKFLSBUF 清楚块设备的buffer

使用方法:

Code: Select all

ioctl(fd, BLKFLSBUF, 0)
fd: 块设备打开的文件描述符。

使用drop_caches 控制 Cache 和 Buffer

echo 1 > /proc/sys/vm/drop_cache 只释放page cache的可回收部分。
echo 2 > /proc/sys/vm/drop_cache 只释放slab cache中的可回收部分。可回收的slab cache是指在调用"kmem_cache_create"函数向slab分配器申请内存时,使用了"SLAB_RECLAIM_ACCOUNT"标志位,主要就是dentry cache和inode cache。
echo 3 > /proc/sys/vm/drop_cache 代表同时释放page cache和reclaimable slab cache。

上面的设置虽然简单但是比较粗暴,使cache的作用基本无法发挥,尤其在系统压力比较大时进行drop cache处理容易产生问题。因为drop_cache是全局在清内存,清的过程会加页面锁,导致有些进程等页面锁时超时,导致问题发生。因此,需要根据系统的状况进行适当的调节寻找最佳的方案。