使用非活动内存对我有利。这段代码存储在RAM或非活动内存中是什么?

时间:2013-04-17 04:23:18

标签: memory memory-management file-io

我正在开发OS X 10.8.3。以下代码很简单。它可以执行两个操作。如果取消注释读取功能,程序将在“地址”处打开文件并将其所有内容传输到数据中。相反,如果取消注释memcpy函数,程序会将mmapped内容复制到数据中。我正在开发一个mac,它将常用文件缓存在RAM的非活动内存中,以便以后更快地访问。我已经关闭了文件控件和mmap中的缓存,因为我正在使用1 GB或更大的大文件。如果我没有设置NOCACHE选项,则整个1 GB将存储在非活动内存中。

如果取消注释读取功能,则程序将按预期运行。没有任何缓存,每次运行程序时,读取整个1 GB大约需要20秒。

但是如果相反,memcpy函数被取消注释会发生一些变化。我仍然没有看到内存增加,第一次运行仍然需要20秒才能复制。但是在上一次执行之后的每次执行都会在一秒钟之内复制。这非常类似于在非活动内存中缓存整个文件的行为,但我从未看到内存增加。即使我没有mmap文件并只执行读取,它也会在一秒钟内同时执行。

必须将某些内容存储在非活动内存中,但我应该如何跟踪它?我想找到存储的内容并将其用于我的优势。

我正在使用活动监视器来查看一般内存大小。我正在使用Xcode Instruments将初始memcpy执行与read和memcpy都被评论的执行进行比较。我认为分配,文件活动,读/写,VM跟踪器或共享内存工具没有区别。

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

int main(int argc, const char * argv[])
{
    unsigned char     *data;
    unsigned char     *mmapdata;
    size_t            length;

    int file = open("address", O_RDONLY);
    fcntl(file, F_NOCACHE, 1);

    struct stat st;
    stat("address", &st);
    length = st.st_size;

    data = malloc(length);
    memset(data,0,length);

    mmapdata = mmap(NULL, length, PROT_READ,MAP_SHARED|MAP_NOCACHE, file, 0);
    if (mmapdata == MAP_FAILED)
        fprintf(stderr, "failure");

//    read(file,data,length);
    close(file);

//    memcpy(data,mmapdata,length);
    munmap(mmapdata,length);

    free(data);

    return 0;
}

更新:

很抱歉,如果我不清楚的话。在程序执行期间,我的RAM的活动存储器部分根据数据I malloc和mmapped文件的大小而增加。这肯定是页面所在的位置。清理后,可用内存量将恢复为之前的状态。非活动内存永远不会增加。有意义的是OS不会真正抛弃那个活动内存,因为空闲内存是无用的,但是这个过程与缓存不同,原因如下。我测试了两个场景。在这两个文件中,我加载了一些文件,这些文件的大小总计超过了我的可用内存。一种情况是我缓存文件而一种我没有。通过缓存,我的非活动内存会增加,一旦我填满我的内存,一切都会慢慢减慢。加载新文件将替换另一个文件的已分配非活动内存,但此过程将比下一个方案花费特别长的时间。下一个场景是缓存。我再次运行该程序几次加载足够的文件来填充我的ram,但非活动内存永远不会增加,活动内存总是恢复正常所以看起来我什么也没做。我映射的文件仍然像以前一样快速加载,但是在正常的时间内加载新文件,替换其他文件。我的系统永远不会因这种方法而变慢。为什么第二种情况更快?

1 个答案:

答案 0 :(得分:4)

如果文件的页面没有驻留在内存中,操作系统如何才能使memcpy'文件上的mmap正常工作?操作系统会提示您不希望缓存数据,但如果它没有选择,或者它与内存没有任何关系,那么它仍然可以。

您的网页优先级最低,因为操作系统认为您不会再次访问它们。但是他们必须是memcpy的居民才能工作,操作系统不会因为拥有空闲内存(100%无用)而将它们丢弃。非活动内存优于可用内存,因为它至少有可能节省I / O操作。