Pourquoi les discussions sur "swap" & # 8221; agir comme si l'information ne pouvait être qu'à un endroit à la fois?

StackOverflow https://stackoverflow.com/questions/147125

Question

J'ai lu des informations sur le lecteur "swappiness" de Linux. accordable, qui contrôle l'agressivité du noyau en échangeant la mémoire des applications sur le disque lorsqu'elles ne sont pas utilisées. Si vous utilisez le terme Google, vous obtiendrez de nombreuses pages telles que this discuter des avantages et des inconvénients. En un mot, l'argument est le suivant:

  

Si votre swappiness est trop faible, les applications inactives accumulent toute la mémoire système que d'autres programmes pourraient vouloir utiliser.

     

Si votre swappiness est trop élevé, lorsque vous réveillez ces applications inactives, le délai sera très long car leur état est relu sur le disque.

Cet argument n'a aucun sens pour moi. Si j'ai une application inactive qui utilise une tonne de mémoire, pourquoi le noyau ne met-il pas sa mémoire en mémoire sur le disque ET ne laisse-t-il pas une autre copie de ces données en mémoire? Cela semble donner le meilleur des deux mondes: si une autre application a besoin de cette mémoire, elle peut immédiatement réclamer la RAM physique et commencer à l'écrire, car une autre copie de celle-ci se trouve sur le disque et peut être remise en place lorsque l'application inactive est activée. up. Et lorsque l'application d'origine se réveille, toutes les pages encore en RAM peuvent être utilisées telles quelles, sans avoir à les extraire du disque.

Ou est-ce que je manque quelque chose?

Était-ce utile?

La solution

Selon ce 1 , c'est exactement ce que Linux fait.

J'essaie encore de comprendre beaucoup de choses, alors tout lien faisant autorité serait apprécié.

Autres conseils

  

Si j'ai une application inactive qui utilise une tonne de mémoire, pourquoi le noyau ne met-il pas sa mémoire en mémoire sur le disque ET ne laisse-t-il pas une autre copie de ces données en mémoire?

Disons que nous l'avons fait. Nous avons écrit la page sur le disque, mais l'avons laissée en mémoire. Un peu plus tard, un autre processus a besoin de mémoire. Nous voulons donc supprimer la page du premier processus.

Nous devons savoir avec une certitude absolue si le premier processus a modifié la page depuis son écriture sur le disque. Si c'est le cas, nous devons l'écrire à nouveau. Pour suivre cela, nous allons supprimer l'autorisation d'écriture du processus sur la page lorsque nous l'avons écrit pour la première fois sur le disque. Si le processus tente d'écrire à nouveau sur la page, il y aura un défaut de page. Le noyau peut noter que le processus a souillé la page (et qu'il faudra donc l'écrire à nouveau) avant de restaurer l'autorisation d'écriture et de permettre à l'application de continuer.

C'est là que réside le problème. Retirer l'autorisation d'écrire de la page est en fait assez coûteux, en particulier dans les ordinateurs multiprocesseurs. Il est important que tous les processeurs purgent leur cache des traductions de page pour s'assurer qu'ils leur enlèvent les droits d'écriture.

Si le processus écrit sur la page, prendre une erreur de page est encore plus coûteux. Je présume qu'un nombre non négligeable de ces pages finiraient par prendre cette faute, ce qui compromet les gains que nous recherchions en la laissant en mémoire.

Alors, est-ce que cela en vaut la peine? Honnêtement, je ne sais pas. J'essaie simplement d'expliquer pourquoi laisser la page en mémoire n'est pas une victoire aussi évidente que ça en a l'air.

(*) Tout cela est très similaire à un mécanisme appelé Copy-On-Write, qui est utilisé lorsqu'un processus fork (). Le processus enfant exécutera très probablement quelques instructions et appellera exec (). Il serait donc ridicule de copier toutes les pages parents. Au lieu de cela, l'autorisation d'écriture est retirée et l'enfant est simplement autorisé à courir. Copy-On-Write est un gain car la faute de page n’est presque jamais prise: l’enfant appelle presque toujours immédiatement exec ().

Même si vous appelez la mémoire des applications sur le disque et la gardez en mémoire, vous devez toujours décider quand une application doit être considérée comme "inactive". et c'est ce que contrôle swapiness. La pagination sur disque coûte cher en IO et vous ne voulez pas le faire trop souvent. Il existe également une autre variable dans cette équation, à savoir le fait que Linux utilise la mémoire restante comme mémoire tampon / cache de disque.

La VM commence par nettoyer les pages et les déplace vers la liste de nettoyage.
Lors du nettoyage de la mémoire anonyme (pour les éléments dépourvus de magasin de sauvegarde de fichier, vous pouvez voir les segments anonymes de mappes / proc // qui ne comportent pas de stockage vnode de système de fichiers), la première chose que la machine virtuelle va faire est prenez le " sale " pages et " nettoyer " puis en écrivant le contenu de la page à échanger. Désormais, lorsque la machine virtuelle manque de mémoire totalement disponible et s'inquiète de sa capacité à autoriser l'utilisation de nouvelles pages gratuites, elle peut consulter la liste des pages "propres" en fonction de la date à laquelle elles ont été utilisées et du type de mémoire. ils vont déplacer ces pages vers la liste libre.

Une fois que les pages de mémoire sont placées sur la liste disponible, elles ne sont plus associées au contenu qu'elles avaient auparavant. Si un programme arrive avec une référence à l'emplacement de mémoire que la page servait auparavant, le programme présentera un défaut majeur et une page (très probablement différente) sera extraite de la liste libre et les données seront lues sur la page à partir du disque. Une fois que cela est fait, la page est en fait toujours "propre" car elle n'a pas été modifiée. Si la machine virtuelle choisit d'utiliser cette page lors de l'échange d'une page différente dans la RAM, la page sera à nouveau «encrassée» ou si l'application écrit sur cette page, elle sera «encrassée». Et puis le processus recommence.

De plus, swappinness est assez horrible pour les applications serveur dans un environnement commercial / transactionnel / en ligne / sensible au temps de latence. Lorsque j'ai des boîtiers de 16 Go de RAM sur lesquels je n'ai pas beaucoup de navigateurs et d'interfaces graphiques, je veux généralement que toutes mes applications soient presque épinglées en mémoire. Le gros de ma mémoire vive est constitué de 8 à 10 Go de java que je ne souhaite JAMAIS jamais paginer sur disque, et les méthodes cruelles disponibles sont des processus comme mingetty (mais même là, les pages glibc de ces applications sont partagés par d’autres applications et réellement utilisés, de sorte que même la taille RSS de ces processus inutiles est principalement partagée, les pages utilisées). Normalement, je ne vois pas plus de quelques 10 Mo de 16 Go nettoyés pour être échangés. Je conseillerais très très peu de swappiness ou zéro swappiness pour les serveurs - les pages inutilisées ne devraient représenter qu'une petite fraction de la mémoire vive globale et tenter de récupérer cette quantité de mémoire RAM relativement petite pour le cache des tampons l'application en cours d'exécution.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top