Je ne peux pas comprendre la page mappée en mémoire et la page anonyme sous Linux. Quelqu'un peut-il l'expliquer avec un exemple? Quelles sont les structures de données du noyau qui leur sont liées?
Les termes corrects sont mappés en mémoire fichiers et mappages anonymes. Quand on se réfère au mappage de mémoire, on se réfère généralement à mmap (2). Il existe 2 catégories d'utilisation de mmap. Une catégorie est les mappages PARTAGÉS vs PRIVÉS. L'autre catégorie est les mappages FILE vs ANONYMOUS. Mélangés, vous obtenez les 4 combinaisons suivantes:
Un mappage de fichier spécifie un fichier, sur disque, qui aura N plusieurs octets mappés en mémoire. La fonction mmap (2) prend comme quatrième argument un descripteur de fichier du fichier à mapper en mémoire. Le cinquième argument est le nombre d'octets à lire, en tant que décalage. Le processus typique d'utilisation de mmap pour créer un fichier mappé en mémoire va
Lorsqu'un fichier est mappé en tant que PRIVÉ, les modifications apportées ne sont pas validées dans le fichier sous-jacent. Il s'agit d'une copie PRIVÉE en mémoire du fichier. Lorsqu'un fichier est mappé PARTAGÉ, les modifications apportées sont automatiquement validées par le noyau dans le fichier sous-jacent. Les fichiers mappés en tant que partagés peuvent être utilisés pour ce que l'on appelle les E/S mappées en mémoire et IPC. Vous utiliseriez un fichier mappé en mémoire pour IPC au lieu d'un segment de mémoire partagée si vous avez besoin de la persistance du fichier
Si vous utilisez strace (1) pour regarder un processus s'initialiser, vous remarquerez que les différentes sections du fichier sont mappées en utilisant mmap (2) comme mappages de fichiers privés. Il en va de même pour les bibliothèques système.
Exemples de sortie de strace (1) où mmap (2) est utilisé pour mapper des bibliothèques au processus.
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
Les mappages anonymes ne sont pas sauvegardés par un fichier. Pour être précis, les 4e (descripteur de fichier) et 5e (décalage) argument de mmap (2) ne sont même pas utilisés lorsque l'indicateur MAP_ANONYMOUS est utilisé comme 3e argument de mmap (2). Une alternative à l'utilisation de l'indicateur MAP_ANONYMOUS consiste à utiliser/dev/zero comme fichier.
Le mot "anonyme" est, selon moi, un mauvais choix en ce sens qu'il semble que le fichier soit mappé de manière anonyme. Au lieu de cela, c'est le fichier qui est anonyme, c'est-à-dire. aucun fichier n'est spécifié.
Les utilisations pour les mappages anonymes privés sont peu nombreuses dans la programmation des terres utilisateur. Vous pouvez utiliser un mappage anonyme partagé afin que les applications puissent partager une région de mémoire, mais je ne connais pas la raison pour laquelle vous n'utiliseriez pas la mémoire partagée SYSV ou POSIX à la place.
Étant donné que la mémoire mappée à l'aide de mappages anonymes est garantie d'être remplie de zéro, il pourrait être utile pour certaines applications qui s'attendent/nécessitent des régions de mémoire remplies de zéro d'utiliser mmap (2) de cette manière au lieu du malloc (2) + memset (2 ) combo.
Si je comprends bien, les pages anonymes sont ainsi nommées, car elles n'ont pas de source de système de fichiers nommée, tandis que les pages mappées sont un mappage de fichier concret. Par exemple, vous pouvez obtenir des pages anonymes en utilisant une simple opération malloc dans n'importe quel processus de l'espace utilisateur ...
À propos des structures du noyau: Évidemment, c'est struct page, mais dans le cas des pages anonymos, vous aurez struct anon_vma assis dans page-> mapping, et dans le cas des pages mappées - struct address_space, qui est connecté à un inode concret.
Je ne sais pas ce que signifie la page mappée en mémoire? Je ne vais donc pas en parler.
Concernant les pages anonymes, il est généralement référé lorsque le noyau effectue la récupération du cadre de page. Les instances de pages anonymes incluent la pile de processus, le tas, la mémoire partagée et toutes les bibliothèques partagées modifiées. Sous Linux, toutes les bibliothèques partagées dynamiques sont mappées à l'espace d'adressage de mémoire virtuelle d'un processus via un appel système comme suit:
firo@linux-6qg8:~> strace -e mmap,openat ls 2>&1 |grep -A1 libc.so
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
mmap(NULL, 3906144, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0)
Toute écriture sur la page qui appartient aux fichiers/bibliothèques MAP_PRIVATEed déclenchera un passage de la page de backend de fichier à une page anonyme.
Par définition, la page anonyme, également appelée mémoire anonyme, est juste une sorte de page qui n'a pas de périphérique backend à échanger lorsque le noyau effectue la récupération du cadre de page. C'est la raison pour laquelle Linux prend en charge la zone d'échange.
Il existe deux types de structures de données du noyau relatives aux pages anonymes.
Afin de récupérer une page anonyme, le noyau doit connaître tous les processus qui utilisent la page anonyme pour changer leurs PTE (entrée de table de page). Nous appelons cela un mappage inverse ou rmap.
struct address_space est utilisé par la mémoire partagée pour maintenir le mappage inverse.
struct anon_vma est utilisé par le reste des pages anonymes pour maintenir le mappage inverse.
Le noyau utilise l'algorithme LRU pour récupérer le cadre de page. Pour le noyau 5.0+, vérifiez la structure lruvec dans la structure pglist_data