linux内存优化[2]_buffer_cache_写文件释放cache

关联文章: 1_读缓存cache优化

1.问题与验证

问题现象

1.htop free命令发现系统 buffer/cache 内存占用高

free -h
total used free shared buff/cache available
Mem: 61Gi 15Gi 569Mi 1.7Gi 45Gi 43Gi
Swap: 30Gi 0.0Ki 30Gi

cat /proc/meminfo or grep -E "Buff|Cache" /proc/meminfo
Buffers: 370568 kB
Cached: 45599784 kB
SwapCached: 0 kB

![[缓存cache高_htop展示.jpg]]

猜想

写文件是否造成系统cache增加?

测试示例1: dd生成文件_确认是否增加系统缓存cache

5.1_dd_验证写文件_cache增加.sh gitee在线

#!/bin/bash

function show_cache_buffer_info()
{
    free -m
    grep -E 'Buffers|Cached' /proc/meminfo
}

sync; echo 3 > /proc/sys/vm/drop_caches
show_cache_buffer_info
dd if=/dev/zero of=test.img bs=1M count=512
show_cache_buffer_info

测试结果
./5.1_dd_验证写文件_cache增加.sh

              total        used        free      shared  buff/cache   available
Mem:           7901        1113        6445           7         343        6544
Swap:          2047           0        2047
Buffers:            2168 kB
Cached:           304968 k
SwapCached:            0 kB

512+0 records in
512+0 records out
536870912 bytes (537 MB, 512 MiB) copied, 0.5336 s, 1.0 GB/s

              total        used        free      shared  buff/cache   available
Mem:           7901        1120        5822           7         958        6529
Swap:          2047           0        2047
Buffers:            7668 kB
Cached:           916124 kB
SwapCached:            0 kB

测试结论:

写文件也会增加系统buffer/cache

2.解决方案

posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED) 主动释放文件句柄, 系统缓存cache

说明:
POSIX_FADV_NORMAL: 没有特殊的建议;让内核根据其默认策略来决定。
POSIX_FADV_SEQUENTIAL: 预期对文件的访问将是顺序的。在这种情况下,内核可能会选择不缓存早期读取的数据,因为它假设这些数据不会再被访问。
POSIX_FADV_RANDOM: 预期对文件的访问将是随机的。这会提示内核尝试保持尽可能多的数据在缓存中。
POSIX_FADV_NOREUSE: 预期对文件中的信息的访问不会重复。内核可能会选择减少对这些数据的缓存。
POSIX_FADV_WILLNEED: 预期不久之后将会访问文件中的信息。内核可能会尽量提前将数据加载到缓存中。
POSIX_FADV_DONTNEED: 文件中的信息不再需要。内核可以丢弃任何与该区域相关的缓存数据。

参考文档:

示例

gitee在线代码5_写文件_是否会生成buffer_cache.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define KB_SIZE 1024
#define MB_SIZE (1024 * KB_SIZE)
#define GB_SIZE (1024 * MB_SIZE)
#define BUF_4K (4 * KB_SIZE)

void show_cache_buffer_info()
{
    system("free -m");
    system("grep -E 'Buffers|Cached' /proc/meminfo");
}

void help()
{
    char* help_str = "\
    默认 正常读文件 \n\
    1 n NOREUSE \n\
    2 d DONTNEED\n";
    printf("%s", help_str);
}

int main(int argc, char* argv[])
{
    // 0.清空系统 cache/buffer
    system("sync; echo 3 > /proc/sys/vm/drop_caches");
    show_cache_buffer_info();

    // 1.创建文件
    int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
    if (fd < 0)
    {
        perror("open");
        exit(1);
    }

    // 2.写文件
    char buf[BUF_4K];
    int count = MB_SIZE * 512;
    while (count > 0)
    {
        write(fd, buf, BUF_4K);
        count -= BUF_4K;
    }

    // 3.释放 缓存
    fsync(fd);      // fsync将写数据落盘,这样才能确保 page cache全部释放成功
    if (argc == 2)
    {
        char opt = *argv[1];
        if (opt == '1' || opt == 'n')
            posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE);
        if (opt == '2' || opt == 'd')
            posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
    }

    // 4.关闭文件
    close(fd);
    show_cache_buffer_info();
}

测试1: ./5_写文件_是否会生成buffer_cache.out

              total        used        free      shared  buff/cache   available
Mem:           7901        1056        6419           7         425        6600
Swap:          2047           0        2047
Buffers:            8708 kB
Cached:           381292 kB
SwapCached:            0 kB

              total        used        free      shared  buff/cache   available
Mem:           7901        1054        5897           7         950        6596
Swap:          2047           0        2047
Buffers:            8720 kB
Cached:           905556 kB
SwapCached:            0 kB

测试2: ./5_写文件_是否会生成buffer_cache.out 2

              total        used        free      shared  buff/cache   available
Mem:           7901        1066        6499           7         336        6590
Swap:          2047           0        2047
Buffers:            2524 kB
Cached:           297488 kB
SwapCached:            0 kB

              total        used        free      shared  buff/cache   available
Mem:           7901        1067        6496           7         337        6589
Swap:          2047           0        2047
Buffers:            3300 kB
Cached:           297800 kB
SwapCached:            0 kB

小结

  • 系统调用 posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); 可以主动释放写文件的缓存

3.个人总结

目前做的产品是智能机器, 和自动驾驶产品, 需要采集与记录大量的数据,日志
posix_fadvise主动释放缓存cache, 主要应用场景

  1. 对于ros2 bag record命令记录的话题数据, 修改ros源代码, 在close关闭文件句柄前, 调用posix_fadvise主动释放cache
  2. 同理 对于程序中记录日志/数据, 如果只是记录, 不查看, 不上传, 调用posix_fadvise也能释放更多的内存空间
  3. 对于开发debug阶段, 需要频繁查看日志, 可能反而会降低性能(需要重新读取文件数据, 加载到内存缓存中)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值