我正在 OS X 10.8.3 上开发。下面的代码很简单。它可以执行两个操作。如果未注释读取功能,则程序将在“地址”处打开文件并将其所有内容传输到数据中。相反,如果取消注释 memcpy 函数,程序会将映射的内容复制到数据中。我正在开发一个 Mac,它将常用文件缓存在 RAM 的非活动内存中,以便将来更快地访问。我在文件控制和 mmap 中都关闭了缓存,因为我正在处理 1 GB 或更大的大文件。如果我没有设置 NOCACHE 选项,则整个 1 GB 将存储在非活动内存中。
如果 read 函数未注释,则程序按预期运行。没有缓存任何内容,每次运行程序时,读取整个 1 GB 大约需要 20 秒。
但是,如果 memcpy 函数未注释,则会发生一些变化。我仍然看到内存没有增加,第一次运行时复制仍然需要 20 秒。但是前一次执行之后的每一次执行,都会在一秒钟内复制。这非常类似于将整个文件缓存在非活动内存中的行为,但我从未看到内存增加。即使我随后不映射文件而只执行读取,它也会在一秒钟内同时执行。
某些东西必须存储在非活动内存中,但是我该如何跟踪它以及如何跟踪它?我想找到正在存储的内容并将其用于我的优势。
我正在使用活动监视器查看一般内存大小。我正在使用 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 的活动内存部分根据我 malloc 的数据和映射文件的大小而增加。这肯定是页面所在的位置。清理后,可用内存量恢复到原来的水平。非活动内存永远不会增加。操作系统不会真正丢弃那些活动内存是有道理的,因为空闲内存是无用的,但由于以下原因,此过程与缓存不同。我测试了两种情况。在这两个文件中,我加载了一些总大小超过我可用内存的文件。一种情况是我缓存文件,另一种情况我不缓存。通过缓存,我的非活动内存增加了,一旦我填满了我的内存,一切都会大大减慢。加载新文件将替换另一个文件' s 分配了非活动内存,但此过程将花费比下一个场景更长的时间。下一个场景是关闭缓存。我再次运行程序几次加载足够的文件来填充我的内存,但非活动内存永远不会增加,活动内存总是恢复正常,所以看起来我什么也没做。我映射的文件仍然像以前一样快速加载,但是映射新文件会在正常时间内加载,替换其他文件。使用这种方法,我的系统永远不会变慢。为什么第二种情况更快?我映射的文件仍然像以前一样快速加载,但是映射新文件会在正常时间内加载,替换其他文件。使用这种方法,我的系统永远不会变慢。为什么第二种情况更快?我映射的文件仍然像以前一样快速加载,但是映射新文件会在正常时间内加载,替换其他文件。使用这种方法,我的系统永远不会变慢。为什么第二种情况更快?