【问题标题】:Memory usage when using boost::iostreams::mapped_file使用 boost::iostreams::mapped_file 时的内存使用情况
【发布时间】:2014-05-05 08:38:22
【问题描述】:

我在这里粘贴一些代码,它使用 boost iostream 来映射然后写入映射文件:

typedef unordered_map<int, string> work;

    int main()
    {

            work d;
            d[0] = "a";

            boost::iostreams::mapped_file_params  params;
            params.path = "map.dat";
            params.new_file_size = 1000000000;
            params.mode = (std::ios_base::out | std::ios_base::in);
            boost::iostreams::mapped_file  mf;
            mf.open(params);
            work* w = static_cast<work*>((void*)mf.data());
            w[0] = d;
            for(int i=1; i <1000000000 ;++i)
            {
                    w->insert(std::make_pair(i, "abcdef"));
            }
            mf.close();

    }

当我在配备 8 个处理器和 16GB RAM 的 centos 6 机器上执行此操作时,我观察到以下情况:

  1. 当数据被插入内存映射文件时,RES(来自 top 命令)不断增加,直到 14GB。 我的印象是,当我映射文件时,VIRT 会增加而不是 RES。 那么,当我们写入 mmap 文件时,是不是先将其写入内存,然后再提交到磁盘?或者是否使用了任何中间缓冲区/缓存?

  2. 在“free”命令的帮助下,我还观察到内存使用量达到 16GB 后,会使用缓冲区。以下是上述代码执行时不同时间的free命令截图:

                total       used       free     shared    buffers     cached
    Mem:      16334688   10530380    5804308          0     232576    9205532
    -/+ buffers/cache:    1092272   15242416
    Swap:     18579448     348020   18231428
    
                total       used       free     shared    buffers     cached
    Mem:      16334688   13594208    2740480          0     232608    9205800
    -/+ buffers/cache:    4155800   12178888
    Swap:     18579448     348020   18231428
    
                total       used       free     shared    buffers     cached
    Mem:      16334688   15385944     948744          0     232648    9205808
    -/+ buffers/cache:    5947488   10387200
    Swap:     18579448     348020   18231428
    
                total       used       free     shared    buffers     cached
    Mem:      16334688   16160368     174320          0     204940    4049224
    -/+ buffers/cache:   11906204    4428484
    Swap:     18579448     338092   18241356
    
                total       used       free     shared    buffers     cached
    Mem:      16334688   16155160     179528          0     141584    2397820
    -/+ buffers/cache:   13615756    2718932
    Swap:     18579448     338092   18241356
    
                total       used       free     shared    buffers     cached
    Mem:      16334688   16195960     138728          0       5440      17556
    -/+ buffers/cache:   16172964     161724
    Swap:     18579448     572052   18007396
    

    这种行为意味着什么?

  3. 与写入内存相比,将数据写入内存映射文件需要花费大量时间。这是什么原因?

    当我处理大量数据时,我想使用内存映射来降低 RES 的使用。但它似乎不是那样工作的。希望将所有数据保存在内存映射文件中,并在需要时将其读回。

    我是否错误地使用了内存映射?或者这就是它的行为方式?

【问题讨论】:

    标签: c++ linux boost memory-mapped-files boost-iostreams


    【解决方案1】:
    1. VIRT 将立即增加(所有页面都映射到进程地址空间)。每当页面被使用时,RES 就会增加,这会导致它们被分页到物理内存中。

      只要有足够的可用内存,就会发生这种情况,之后操作系统开始从保留集中清除 LRU 页面(除非它们是 VirtualLock/mlock-ed 或其他不可移动的(如内核页面、DMA缓冲区、安全敏感数据等)。

      因此,操作系统会乐观地将页面保留尽可能长的时间(只要没有其他进程争用内存,就会提高性能)。

    2. 这表示操作系统正在完成它的工作。

    3. 您正在写入磁盘。磁盘访问(很多)比内存访问慢。数据实际写入磁盘的频率取决于调优。这个答案列出了一些 Linux 上可用的调整参数(您似乎正在使用):

    【讨论】:

    • 我希望我的应用程序占用不超过 20% 或最多 30% 的实际可用 RAM。我怎么能设置这个限制?我希望操作系统将所有数据刷新到磁盘并且不在内存中保留任何页面。我尝试了您共享的链接中提供的选项,但它们无法解决此问题。另外,这里有个问题——脏页迟早会被写入磁盘,但它不是从内存中删除的吗?就像您解释的那样,操作系统仍将其保存在内存中以进行优化?这正是我不想要的。
    • ulimit 在linux上应该够用了,我觉得(unix.stackexchange.com/questions/44985/…),或者直接调用setrlimit
    猜你喜欢
    • 1970-01-01
    • 2010-10-14
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 2015-02-03
    相关资源
    最近更新 更多