我們都知道,Linux一個行程使用的記憶體分為2種:
-
file-backed pages(有檔案背景的頁面,比如程式碼段、比如read/write方法讀寫的檔案、比如mmap讀寫的檔案;他們有對應的硬碟檔案,因此如果要交換,可以直接和硬碟對應的檔案進行交換),此部分頁面進page cache
-
anonymous pages(匿名頁,如stack,heap,CoW後的資料段等;他們沒有對應的硬碟檔案,因此如果要交換,只能交換到虛擬記憶體-swapfile或者Linux的swap硬碟分割槽),此部分頁面,如果系統記憶體不充分,可以被swap到swapfile或者硬碟的swap分割槽
下麵我們看看,mmap的各種情況,與上面的頁面型別之間的關係。
-
不對映任何檔案(MAP_ANONYMOUS),又分為私有和共享對映2種情況:
1.1 私有對映(MAP_PRIVATE)
這個是malloc庫函式之類底層的實現之一,最後對應匿名頁。
比如應用程式呼叫:
int *p= malloc(1024*1024*80);
對應的系統呼叫是:mmap2(NULL, 83890176, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
1.2 共享對映MAP_SHARED
用作有親緣關係行程間的共享記憶體通訊,最後對應匿名頁。
-
對映磁碟裡面的檔案,又分為共享對映和私有對映
2.1 共享對映: 這個時候頁面dirty後要回寫磁碟,是有檔案背景(file-backed)的頁面
2.2 私有對映:這個時候是CoW(寫時複製)頁面,最後變成匿名頁
-
對映tmpfs檔案,一般做行程間共享記憶體通訊用(不需要親緣關係),以共享方式對映,看起來是類似2.1有file-backed,但是file本身也是記憶體,所以本質上面還是匿名頁,程式碼實體:
-
對映framebuffer等,視訊記憶體,多媒體,這些是為了減少一次使用者空間往核心空間的記憶體複製。這個時候mmap對應的檔案是/dev/下麵的裝置檔案。程式碼案例:
int fb;
unsigned char* fb_mem;
fb = open (“/dev/fb0”, O_RDWR);
fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
memset (fb_mem, 0, 1024*768 );
內容轉載自公眾號:Linuxer