我正在開發OS X 10.8.3。以下代碼很簡單。它可以執行兩個操作。如果閱讀功能未被註釋,則程序將在「地址」處打開該文件並將其全部內容轉換爲數據。相反,如果memcpy函數未被註釋掉,程序會將mmapped內容複製到數據中。我正在開發一個mac,它在RAM的非活動內存中緩存常用文件,以便更快速地訪問。我關閉了文件控制和mmap中的緩存,因爲我正在處理1 GB或更大的大文件。如果我沒有設置NOCACHE選項,整個1 GB將被存儲在非活動內存中。使用無效內存對我有利。這段代碼存儲在RAM或非活動內存中是什麼?
如果讀取功能未註釋,程序將按預期運行。沒有任何內容被緩存,每次程序運行時,大約需要20秒才能讀取整個1 GB。
但是,如果取而代之的是memcpy函數未註釋的東西發生了變化。儘管如此,我仍然看不到內存的增加,並且在第一次運行時仍需要20秒才能複製。但是之前的每一次執行,都會在一秒之內複製。這非常類似於將整個文件緩存在非活動內存中的行爲,但我從來沒有看到內存的增加。即使我沒有對文件進行mmap映射並且只執行讀取操作,它也會在相同的時間內執行,而不會執行讀取操作。
某些東西必須存儲在不活動的內存中,但是我該如何跟蹤它?我想找到正在存儲的內容,並將其用於我的優勢。
我正在使用活動監視器來查看一般內存大小。我使用Xcode Instruments將初始memcpy執行與read和memcpy都進行了註釋的執行進行比較。我在分配,文件活動,讀/寫,虛擬機跟蹤器或共享內存工具中看不到任何區別。
#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;
}
UPDATE:
很抱歉,如果我還不清楚。在程序執行期間,我的RAM的活動內存部分根據數據I malloc和mmapped文件的大小而增加。這無疑是網頁所在的位置。清理之後,可用內存量恢復到之前的狀態。不活躍的內存永遠不會增加。因爲可用內存是無用的,所以操作系統不會真的丟掉活動內存,但這個過程與緩存不同,原因如下。我測試了兩種情況。在這兩個文件中,我加載了大小超過我的可用內存大小的文件。一個場景我緩存文件,一個我沒有。隨着緩存,我的不活動內存增加,一旦我填滿我的內存,一切都會大大減慢。加載新文件將替換另一個文件分配的非活動內存,但此過程需要的時間比下一個場景要長得多。下一個場景是緩存關閉。我再次運行該程序幾次加載足夠的文件來填充我的內存,但不活動的內存永遠不會增加,活動內存總是恢復正常,所以看起來我什麼也沒做。我已經映射的文件仍然像以前一樣快速加載,但是在正常時間內加載新文件並替換其他文件。用這種方法,我的系統永遠不會變慢。爲什麼第二種情況會更快?
我添加了一個更新到我的問題的結尾。添加評論太長了。 – James491
更新:第二種情況更快,因爲您使用的內存優先級較低,因此不會踢出緩存中重用的數據。 –