Linux gestion de la mémoire est différent des autres systèmes. Le principe clé est que la mémoire qui n'est pas utilisée est de la mémoire gaspillée. À de nombreux égards, Linux essaie d'optimiser l'utilisation de la mémoire, ce qui entraîne (la plupart du temps) de meilleures performances.
Ce n'est pas que "rien ne fonctionne" dans Linux, mais que son comportement est un peu différent de ce que vous attendez. Lorsque les pages de mémoire sont tirées du fichier mmapped, le système d'exploitation doit décider quelles pages de mémoire physique il va libérer (ou échanger) pour pouvoir l'utiliser. Il cherchera les pages qui sont plus faciles à échanger (ne nécessitent pas d'écriture immédiate sur le disque) et seront moins susceptibles d'être réutilisées.
L'appel madvice() POSIX sert à indiquer au système comment votre application utilisera les pages. Mais comme son nom l'indique, il s'agit d'un conseil afin que le système d'exploitation soit mieux équipé pour prendre des décisions de pagination et d'échange. Ce n'est ni une politique ni un ordre.
Pour démontrer les effets de madvice() sur Linux, j'ai modifié un des exercices que je donne à mes étudiants. Voir le complete source code here. Mon système est 64 bits et dispose de 2 Go de RAM, dont environ 50% est actuellement utilisé. En utilisant le programme pour convertir un fichier de 2 Go, lisez-le séquentiellement et jetez tout. Il signale l'utilisation du RSS tous les 200 Mo est lu.Les résultats sans madvice():
<[email protected]> ~% ./madvtest file.dat n
0 : 3 MB
200 : 202 MB
400 : 402 MB
600 : 602 MB
800 : 802 MB
1000 : 1002 MB
1200 : 1066 MB
1400 : 1068 MB
1600 : 1078 MB
1800 : 1113 MB
2000 : 1113 MB
Linux continué à pousser les choses de la mémoire jusqu'à environ 1 Go a été lu. Après cela, il a commencé à faire pression sur le processus lui-même (puisque l'autre 50% de la mémoire était active par les autres processus) et stabilisé jusqu'à la fin du fichier.
Maintenant, avec madvice():
<[email protected]> ~% ./madvtest file.dat y
0 : 3 MB
200 : 202 MB
400 : 402 MB
600 : 494 MB
800 : 501 MB
1000 : 518 MB
1200 : 530 MB
1400 : 530 MB
1600 : 530 MB
1800 : 595 MB
2000 : 788 MB
Notez que Linux a décidé d'allouer des pages au processus que jusqu'à ce qu'elle atteigne environ 500 Mo, beaucoup plus tôt que sans madvice(). En effet, après cela, les pages actuellement en mémoire semblaient beaucoup plus précieuses que les pages marquées comme accès séquentiel par ce processus. Il y a un seuil dans le VMM qui définit quand commencer à abandonner les anciennes pages du processus.
Vous pouvez vous demander pourquoi Linux a continué d'allouer des pages jusqu'à environ 500 Mo et ne s'est pas arrêté beaucoup plus tôt, car ils ont été marqués comme accès séquentiel. C'est que soit le système avait suffisamment de pages de mémoire libre de toute façon, ou les autres pages de résidents étaient trop vieux pour rester. Entre garder des pages anciennes en mémoire qui ne semblent plus être utiles, et amener plus de pages pour servir un programme qui tourne maintenant, Linux choisit la deuxième option.
Même s'ils étaient marqués comme accès séquentiel, c'était juste un conseil. L'application peut toujours vouloir revenir à ces pages et les relire. Ou une autre application dans le système. L'appel de madvice() ne dit que ce que l'application elle-même fait, Linux prend en considération l'image plus grande.
Cela peut être pertinent ou non, mais il est utile de savoir: utilisez-vous un système 32 bits ou 64 bits? Savez-vous que vous ne devriez pas convertir un 1GB dans un système 32 bits? (même si vous utilisez un système 64 bits, vous pouvez être préoccupé par la portabilité). – Juliano
Tous les systèmes sont 64 bits (avec des pointeurs et des décalages de fichiers de 64 bits) et je pourrais réussir à mapper des fichiers de 40 Go. Je viens de résumer le problème à 1 Go pour des raisons de reproductibilité. – Dave
@Sven. Il y a des cas où l'utilisation d'un mappage de mémoire est inévitable, par exemple lorsqu'un appel de bibliothèque nécessite une région de mémoire, plutôt qu'un fichier. Votre suggestion n'est donc pas utile et ne répond pas à la question. En ce qui concerne la réponse, apparemment sur Linux MMAP_SEQUENTIAL est à peu près * cassé *. La partie lecture anticipée fonctionne, mais pas la partie récupération de page. Et la seule façon de suggérer à Linux qu'en fait ces pages sont de bons candidats est de démêler la région (et de la cartographier à nouveau). –