I termini corretti sono file mappati in memoria e mappature anonime. Quando ci si riferisce alla mappatura della memoria, di solito ci si riferisce a mmap(2). Esistono 2 categorie per l'utilizzo di mmap. Una categoria è mappature CONDIVISE vs PRIVATE. L'altra categoria è la mappatura FILE vs ANONIMO. Mescolati insieme si ottengono le 4 seguenti combinazioni:
- MAPPATURA DI FILE PRIVATI
- MAPPATURA FILE CONDIVISI
- MAPPATURA ANONIMA PRIVATA
- MAPPATURA ANONIMA CONDIVISA
Un File Mapping specifica un file, su disco, che avrà N molti byte mappati in memoria. La funzione mmap(2) accetta come quarto argomento un descrittore di file per il file da mappare in memoria. Il quinto argomento è il numero di byte da leggere, come offset. Il tipico processo di utilizzo di mmap per creare un file mappato in memoria va
- apri(2) file per ottenere un descrittore di file.
- fstat(2) il file per ottenere la dimensione dalla struttura dei dati del descrittore di file.
- mmap(2) il file utilizzando il descrittore di file restituito da open(2).
- chiudi(2) il descrittore di file.
- fai qualunque cosa al file mappato in memoria.
Quando un file viene mappato come PRIVATE, le modifiche apportate non vengono salvate nel file sottostante. È una copia PRIVATA in memoria del file. Quando un file viene mappato SHARED, le modifiche apportate vengono salvate automaticamente dal kernel nel file sottostante. I file mappati come condivisi possono essere utilizzati per ciò che viene chiamato I/O mappato in memoria e IPC. Useresti un file mappato in memoria per IPC invece di un segmento di memoria condivisa se hai bisogno della persistenza del file
Se usi strace(1) per osservare l'inizializzazione di un processo, noterai che le diverse sezioni del file sono mappate usando mmap(2) come mapping di file privati. Lo stesso vale per le librerie di sistema.
Esempi di output da strace(1) dove mmap(2) viene utilizzato per mappare le librerie al processo.
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42238, ...}) = 0
mmap(NULL, 42238, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff7ca71e000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356\341n8\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1926760, ...}) = 0
mmap(0x386ee00000, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x386ee00000
Le mappature anonime non sono supportate da un file. Per essere precisi, il 4° (descrittore di file) e il 5° (offset) argomento di mmap(2) non sono nemmeno usati quando il flag MAP_ANONYMOUS è usato come 3° argomento di mmap(2). Un'alternativa all'utilizzo del flag MAP_ANONYMOUS consiste nell'utilizzare /dev/zero come file.
La parola "Anonimo" è, per me, una scelta sbagliata in quanto suona come se il file fosse mappato in modo anonimo. Invece, è il file che è anonimo, vale a dire. non c'è un file specificato.
Gli usi per le mappature anonime private sono pochi nella programmazione del territorio degli utenti. Potresti utilizzare una mappatura anonima condivisa in modo che le applicazioni possano condividere una regione di memoria, ma non conosco il motivo per cui non utilizzeresti invece la memoria condivisa SYSV o POSIX.
Dato che la memoria mappata utilizzando le mappature anonime è garantita per essere riempita con zero, potrebbe essere utile per alcune applicazioni che prevedono/richiedono regioni di memoria riempite con zero utilizzare mmap(2) in questo modo invece di malloc(2) + memset(2 ) combinato.
A quanto ho capito, le pagine anonime sono così chiamate, perché non hanno una sorgente di file system denominata, mentre le pagine mappate sono una mappatura di file concreti. Ad esempio, puoi ottenere pagine anonime utilizzando una semplice operazione malloc in qualsiasi processo dello spazio utente...
Informazioni sulle strutture del kernel:ovviamente è struct page , ma nel caso delle pagine anonime avrai struct anon_vma seduto in pagina->mappatura, e in caso di pagine mappate - struct address_space , che è connesso con l'inode concreto.