remi_2
Bonjour,
sur ma machine 64 bits double core qui a 4Gigs de RAM je lance un programme qui est constitué de deux process identiques qui doivent se partager 4G ram.
Au bout d'un moment, la ram est saturée, chacun des deux process occupe 2G en ram et commence à allouer du swap. La consommation mémoire se stabilise lorsque chaque process a généré 1.5 Go de swap. cela veut en gros dire que chaque process aurait besoin de 3.5Gig de ram à lui tout seul pour tourner en RAM, mais le fait qu'ils swappent ne les empèche pas réellement de fonctionner.
Au bout d'un moment, je tue l'un des deux process. Le process restant se retrouve donc avec 2 Go de libres supplementaires, et je m'attendais à ce qu'il se recharge totalement en RAM très rapidement, c'est à dire à voir la quantité de swap utilisée baisser et la quantité de ram consommée augmenter jusqu' a 3.5 Gig, mais il n'en est rien.
Je me demande donc comment je peux interpreter ça, est-ce que ça veut dire que tout ce qui est dans le swap n'est en fait que très peu ou plus du tout utilisé par mon process?
Y a-t-il des moyens de paramétrer le fonctionnement du swap sous linux?
Merci
Anvil
La gestion de la "Virtual Memory" (ram/swap combo) est complexe. Mais d'abord il faut que tu saches qu'un processus n'alloue pas de swap. Un processus alloue de la memoire et c'est le noyau qui decide, quand il n'y a plus de memoire physique libre de passer une page memoire en swap. Les pages memoire "swapées" sont celles qui sont moins accedees.
Il faut aussi que tu saches que le noyau occupe a tout instant l'integralite de la memoire physique. Soit par la memoire utilisateur (le type de memoire qu'un processus peut allouer), soit par du cache disque. Ce cache est extremement important et accelere grandement de maniere transparente les acces aux disques.. qui sont, comme chacun sait, lents. Si tu devais lire un fichier 20 fois, le fichier serait effectivement lu sur disque la premiere fois, mais les 19 autres fois il serait relu a partir de la memoire. Suivant ce qui lui est demande, le noyau peut a tout moment decide de passer en swap une page memoire utilisateur vieille pour creer du cache.
La question a se poser maintenant est : quel bien y-a-t'il de "de-swaper" une page memoire si celle-ci n'est pas demandee ? Peu, surtout si elle doit se retrouver a nouveau dans le swap a la prochaine allocation de memoire sans avoir ete consulee. Donc, quand tu as tue ton 1er processus, le noyau a libere toute la memoire utilisateur qu'il utilisait. Mais si ton 2eme processus ne se reveille pas et n'utilise pas la memoire qu'il a alloue, le noyau ne deswappera pas sa memoire et preferera creer du cache. Si, par la suie, le 2eme processus avait besoin de la memoire qu'il avait alloue plus tot, le noyau la de-swapera a ce moment-la.
Je le repete, la gestion de la VM dans le noyau est complexe et les reglage par defaut sont plutot bien calibre pour une utilisation `standard'. Meme si le comportement de la VM est configurable, je te deconseille d'y toucher. Si quelqu'un te dis de faire des echo dans /proc/sys, ne le fait pas a la va-vite et certainement pas sans avoir lu quelques dizaines de pages de documentation : tu ne voudrais pas avoir a appuyer sur le bouton reset, n'est-ce pas ? :p
remi_2
Merci pour les explications,
En fait , chaque processus est sensé utiliser périodiquement toutes les données qu'il place en mémoire, et je m'attendais donc à ce que toutes les pages qui avaient été placées sur le disque (à cause du manque de RAM causé par la seconde instance du processus) soient rapidement redemandées.
je raffine donc un peu ma question :
je me place dans la situation ou je viens de tuer mon 2nd processus, qui libère donc 2Go de Ram. Si à ce moment mon premier processus (qui tourne toujours à plein régime, puisqu'il occupe 100% d'un des deux cores de mon AMD64) a besoin d'acceder à des données qui sont situées dans une page qui se trouve dans la partition de swap, que fait le noyau :
1) Il va réallouer de la RAM dans les 2Go qui viennent d'être libérés pour charger la page demandée? Dans ce cas toutes les pages en swap devraient rapidement se retrouver en RAM (en une itération de la "boucle principale" de mon processus)
2) il va 'swapper' la page demandée avec une autre page en RAM qui n'a pas été utilisée depuis longtemps, et qui va donc se retrouver sur le disque? (dans ce cas la consommation de RAM n'augmentera plus jamais et il y aura toujours des accès disque à chaque itération de la boucle principale de mon processus)
j'espère que je suis plus clair maintenant?
Anvil
En fait , chaque processus est sensé utiliser
censé, avec un c. Quand tu peux remplacer par "supposé", c'est "censé". Si on parle de sens, c'est "sensé" (sensé <-> insensé).
je me place dans la situation ou je viens de tuer mon 2nd processus, qui libère donc 2Go de Ram. Si à ce moment mon premier processus (qui tourne toujours à plein régime, puisqu'il occupe 100% d'un des deux cores de mon AMD64) a besoin d'acceder à des données qui sont situées dans une page qui se trouve dans la partition de swap, que fait le noyau :
1) Il va réallouer de la RAM dans les 2Go qui viennent d'être libérés pour charger la page demandée? Dans ce cas toutes les pages en swap devraient rapidement se retrouver en RAM (en une itération de la "boucle principale" de mon processus)
2) il va 'swapper' la page demandée avec une autre page en RAM qui n'a pas été utilisée depuis longtemps, et qui va donc se retrouver sur le disque? (dans ce cas la consommation de RAM n'augmentera plus jamais et il y aura toujours des accès disque à chaque itération de la boucle principale de mon processus)
j'espère que je suis plus clair maintenant?
Pareil en fait. Mais tu n'as pas l'air de saisir que la notion de swap est completement etrangere a un processus.
Et ta reponse depend completement du contexte : quand le noyau a besoin de deswaper une page, si la page la plus ancienne en memoire physique est une page de cache disque, le noyau degagera une page memoire allouée au cache disque pour en faire une page memoire utilisateur. Si la page la plus ancienne en memoire physique est une page de memoire utilisateur, elle echangera sa place avec la page sur le fichier de swap (oui, une partition c'est un fichier aussi.. :p).
Tout est fonction de l'utilisation du systeme.
remi_2
Oui bien sur tout est fonction de l'utilisation du système, et c'est le système qui gère les allocations de mémoire et la pagination et pas les programmes eux mêmes (en général, car rien en t'empeche de gérer toi même les allers retours de tes structures de données entre la RAM et le disque dur si le coeur t'en dit), mais là justement le cadre d'utilisation est bien précis :
Normalement en 20 minutes de calcul mon programme sollicite la totalité de ses structures de données, dont une bonne moitié se trouve dans la partition de swap lorsque je libère d'un seul coup 2Go de RAM.
Je ne comprend pas pourquoi le system monitor me dit toujours que mon process occupe 2Go en RAM et 1.5Go en swap au lieu de 3.5Go en RAM après que toutes les données (y compris celles qui sont sur des pages écrites sur le DD) ont été utilisées par le programme plusieurs fois, et qu'aucun autre programme ne tourne sur la machine à part les démons...
Mais si j'extrapole un peu que tu me dis, les pages qui étaient sur le disque dur et qui sont chargées dans le disk cache en RAM apparaissent toujours comme étant swappées dans le system monitor?
Ce qui me surprend dans ce que tu me dis c'est qu'apparemment la quantité de disk cache rapportée par la commande 'free' serait erronée? sur mon système 'free' liste juste que 180Mo de RAM sont allouées pour le disk cache, cette quantité a l'air constante.
Anvil
Tu n'accedes pas a toute ta memoire en meme temps. Ton algorithme accede surement sequentiellement a la liste de structures.... et le moment venu de deswaper une page, le noyau se demandera forcement "a la place de quoi je vais la mettre ?"
Anvil
Ca me revient.. t'as mate le `man mlock' et celui de mlockall sinon ?
remi_2
J'ai l'impression d'être dans un dialogue de sourd!!!
bien sur que mon programme n'accède pas à toute la mémoire en même temps, puisqu'il le fait en 20 minutes environ!
je recommence :
mon programme consomme 3.5Go de memoire
je force ces 3.5Go à se fractionner en deux parties, une en RAM, l'autre sur le disque en lançant un deuxième programme qui consomme de la mémoire aussi
je tue ce deuxième programme.
Pourquoi après deux heures d'exécution linux n'a-t-il toujours pas rechargé l'intégralité des structures de données de mon programme en RAM au lieu d'en laisser la moitié sur le disque?! C'est complètement con, y'a 2Go de ram libre et j'ai mon programme qui swappe...
enfin bref... il ne me reste qu'a me taper le chapitre 16 de "understanding the linux kernel"
:-?
remi_2
ps : merci pour le tuyau mlock et mlockall, mais c'est un peu brutal pour l'utilisation que je vise.
Cygn
Il y a un moyen de régler la "volonté" du noyau à utliser le swap, en temps réel. c dans:
/proc/sys/vm/swappiness
tu peux modifier la valeur là-dedans par
echo 1 > /proc/sys/vm/swappiness
par exemple. Plus la valeur est grand (max 99 il me semble) plus le système a tendance à utiliser le swap. Plus c petit, plus le swap devient un dernier recours.
Ce paramètre a causé pas mal de débat à son introduction, à savoir s'il valait mieux mettre petit ou grand. La question n'est pas résolue, mais les 2 grandes écoles sont:
- mettre le swappiness à 0: système + réactive pour une utilisation desktop, le problème étant, qd tu commence à swapper, il n'ya déjà plus beaucoup de RAM dispo, donc c lent.
- mettre le max à swappiness, pour avoir le + de RAM dispo sous la main.
Le compromis a été de mettre le max pour des gens qui compilent du kernel (ou compilent des grooooos trucs) pour laisser la ram au compilateur, et de réduire la valeur pour les autres.
Pour ma part, jai le swappiness à 1, sur mon Xeon 2.4G 1.5 G RAM, et je le trouve nettement + réactive par rapport à 60 d'origine et c vraiment rare que la machine aille chercher le swap.
Enfin, pour finir, tripote un peu ton swappiness, tu verras bien...
j'oubliais: il y a qq'1 qui a pendu un patch kernel pour régler automatiquement ce param en fct de l'usage, mais je pense que ça n'a pas été inclus, chais plus pourquoi.