GNU/Linux >> Tutoriels Linux >  >> Linux

Linux - Linux effectue-t-il un "échange opportuniste", ou est-ce un Theth ?

Supposons qu'un programme demande de la mémoire, mais qu'il ne reste pas assez de mémoire libre. Il existe plusieurs manières différentes pour Linux de répondre. Une réponse consiste à sélectionner une autre mémoire utilisée, qui n'a pas été consultée récemment, et à déplacer cette mémoire inactive vers l'échange.

Cependant, je vois de nombreux articles et commentaires qui vont au-delà de cela. Ils disent que même lorsqu'il y a une grande quantité de mémoire libre, Linux décidera parfois d'écrire de la mémoire inactive à échanger. Écrire à l'avance pour échanger signifie que lorsque nous voulons éventuellement utiliser cette mémoire, nous n'avons pas à attendre une écriture sur disque. Ils disent que c'est une stratégie délibérée pour optimiser les performances.

Ont-ils raison ? Ou est-ce un mythe ? Citez vos sources.

Veuillez comprendre cette question en utilisant les définitions suivantes :

  • échanger
  • gratuit memory – la mémoire « libre » affichée par la commande free. C'est le MemFree valeur de /proc/meminfo . /proc/meminfo est un fichier texte virtuel fourni par le noyau. Voir proc(5) ou la documentation RHEL.
  • même lorsqu'il y a une grande quantité de mémoire libre – à des fins d'argumentation, imaginez qu'il y ait plus de 10 % de mémoire libre.

Références

Voici quelques termes de recherche :linux "échange opportuniste" OU (échange "lorsque le système n'a rien de mieux à faire" OU "quand il n'a rien de mieux à faire" OU "lorsque le système est inactif" OU "pendant les périodes d'inactivité")

Dans le deuxième résultat le plus élevé sur Google, un utilisateur de StackExchange demande "Pourquoi utiliser le swap alors qu'il y a plus qu'assez d'espace libre dans la RAM ?", et copie les résultats du free commande affichant environ 20 % de mémoire libre. En réponse à cette question spécifique, je vois que cette réponse est très appréciée :

Linux commence à échanger avant que la RAM ne soit remplie. Ceci est fait pour
améliorer les performances et la réactivité :

  • Les performances sont améliorées car parfois la RAM est mieux utilisée pour le cache disque que pour stocker la mémoire programme. Il est donc préférable de remplacer un
    programme inactif pendant un certain temps et de conserver à la place les fichiers
    souvent utilisés dans le cache.

  • La réactivité est améliorée en échangeant des pages lorsque le système est inactif, plutôt que lorsque la mémoire est pleine et qu'un programme est en cours d'exécution
    et demande plus de RAM pour terminer une tâche.

L'échange ralentit le système, bien sûr, mais l'alternative à
l'échange n'est pas de ne pas échanger, c'est d'avoir plus de RAM ou d'utiliser moins de RAM.

Le premier résultat sur Google a été marqué comme un doublon de la question ci-dessus :-). Dans ce cas, le demandeur a copié les détails indiquant 7 Go de MemFree , sur 16 Go. La question a sa propre réponse acceptée et votée :

L'échange uniquement lorsqu'il n'y a pas de mémoire libre n'est le cas que si vous définissez swappiness à 0. Sinon, pendant le temps d'inactivité, le noyau échangera de la mémoire. Ce faisant, les données ne sont pas supprimées de la mémoire, mais plutôt une copie est faite dans la partition d'échange.

Cela signifie que, si la situation se présente où la mémoire est épuisée, il n'est pas nécessaire d'écrire sur le disque sur-le-champ. Dans ce cas, le noyau peut simplement écraser les pages mémoire qui ont déjà été permutées, dont il sait qu'il possède une copie des données.

L'swappiness Le paramètre contrôle simplement combien il fait cela.

L'autre citation ne prétend pas explicitement que les données échangées sont également conservées en mémoire. Mais il semble que vous préféreriez cette approche, si vous échangez même à des moments où vous avez 20 % de mémoire libre, et que la raison pour laquelle vous le faites est d'améliorer les performances.

Pour autant que je sache, Linux prend en charge la conservation d'une copie des mêmes données à la fois dans la mémoire principale et dans l'espace d'échange.

J'ai également remarqué l'affirmation courante selon laquelle «l'échange opportuniste» se produit «pendant les périodes d'inactivité». Je comprends que c'est censé m'aider à me rassurer sur le fait que cette fonctionnalité est généralement bonne pour les performances. Je ne l'inclus pas dans ma définition ci-dessus, car je pense qu'elle contient déjà suffisamment de détails pour faire une belle question claire. Je ne veux pas rendre cela plus compliqué que nécessaire.

Motivation initiale

au sommet montre `swout` (échange) lorsque j'ai des gigaoctets de mémoire libre. Pourquoi ?

Il existe quelques rapports comme celui-ci, sur l'écriture Linux à échanger lorsqu'il y a beaucoup de mémoire libre. « L'échange opportuniste » pourrait expliquer ces rapports. Dans le même temps, au moins une cause alternative a été suggérée. Comme première étape dans l'examen des causes possibles :Linux effectue-t-il parfois une "permutation opportuniste" telle que définie ci-dessus ?

Dans l'exemple que j'ai rapporté, la question a maintenant reçu une réponse. La cause n'était pas un échange opportuniste.

Réponse acceptée :

Linux ne fait pas de "permutation opportuniste" comme défini dans cette question.

Les références principales suivantes ne mentionnent pas du tout le concept :

  1. Comprendre le gestionnaire de mémoire virtuelle Linux. Un livre en ligne de Mel Gorman. Écrit en 2003, juste avant la sortie de Linux 2.6.0.
  2. Documentation/admin-guide/sysctl/vm.rst. Il s'agit de la documentation principale des paramètres ajustables de la gestion de la mémoire virtuelle Linux.
En relation :Rediriger STDERR et STDOUT vers différentes variables sans fichiers temporaires ?

Plus précisément :

10.6 Démon de pageout (kswapd)

Historiquement kswapd utilisé pour se réveiller toutes les 10 secondes mais maintenant il n'est réveillé par l'allocateur de page physique que lorsque le nombre de pages libres dans une zone est atteint. […] Sous une pression mémoire extrême, les processus feront le travail de kswapd de manière synchrone. […] kswapd continue de libérer des pages jusqu'à ce que le filigrane pages_high soit atteint.

Sur la base de ce qui précède, nous ne nous attendons à aucun échange lorsque le nombre de pages gratuites est supérieur au "high watermark".

Deuxièmement, cela nous indique le but de kswapd est de créer plus de pages gratuites.

Lorsque kswapd écrit une page mémoire à échanger, il libère immédiatement la page mémoire. kswapd ne conserve pas de copie de la page échangée en mémoire .

Linux 2.6 utilise le « rmap » pour libérer la page. Sous Linux 2.4, l'histoire était plus complexe. Lorsqu'une page était partagée par plusieurs processus, kswapd n'était pas en mesure de la libérer immédiatement. C'est de l'histoire ancienne. Tous les articles liés concernent Linux 2.6 ou supérieur.

échange

Ce contrôle est utilisé pour définir l'agressivité avec laquelle le noyau permutera
les pages mémoire. Des valeurs plus élevées augmenteront l'agressivité, des valeurs inférieures
diminueront la quantité d'échange. Une valeur de 0 indique au noyau de ne pas
initier l'échange jusqu'à ce que le nombre de pages libres et sauvegardées par des fichiers est inférieur
à la ligne des hautes eaux d'une zone.

Cette citation décrit un cas particulier :si vous configurez le swappiness la valeur doit être . Dans ce cas, nous ne devons en outre pas nous attendre à un échange tant que le nombre de pages de cache n'est pas tombé au niveau supérieur. En d'autres termes, le noyau essaiera de supprimer presque tout le cache de fichiers avant de commencer l'échange. (Cela peut entraîner des ralentissements massifs. Vous devez disposer d'un cache de fichiers ! Le cache de fichiers est utilisé pour contenir le code de tous vos programmes en cours d'exécution 🙂

Que sont les filigranes ?

Les citations ci-dessus soulèvent la question :quelle est la taille des réservations de mémoire "filigrane" sur mon système ? Réponse :sur un "petit" système, les filigranes de zone par défaut peuvent atteindre 3 % de la mémoire. Cela est dû au calcul du filigrane "min". Sur les systèmes plus grands, les filigranes seront une proportion plus faible, approchant 0,3 % de la mémoire.

Donc, si la question concerne un système avec plus de 10 % de mémoire libre, les détails exacts de cette logique de filigrane ne sont pas significatifs.

Les filigranes pour chaque "zone" individuelle sont affichés dans /proc/zoneinfo , comme documenté dans proc(5). Un extrait de mon zoneinfo :

Node 0, zone    DMA32
  pages free     304988
        min      7250
        low      9062
        high     10874
        spanned  1044480
        present  888973
        managed  872457
        protection: (0, 0, 4424, 4424, 4424)
...
Node 0, zone   Normal
  pages free     11977
        min      9611
        low      12013
        high     14415
        spanned  1173504
        present  1173504
        managed  1134236
        protection: (0, 0, 0, 0, 0)

Les "filigranes" actuels sont min , low , et high . Si jamais un programme demande suffisamment de mémoire pour réduire free en dessous de min , le programme entre "récupération directe". Le programme est mis en attente pendant que le noyau libère de la mémoire.

Nous voulons éviter la récupération directe si possible. Donc, si free tomberait en dessous du low filigrane, le noyau réveille kswapd . kswapd libère de la mémoire en permutant et/ou en supprimant les caches, jusqu'à ce que free est supérieur à high à nouveau.

Qualification supplémentaire :kswapd s'exécutera également pour protéger le montant total de lowmem_reserve, pour l'utilisation du noyau lowmem et DMA. Le lowmem_reserve par défaut est d'environ 1/256 des premiers 4 Go de RAM (zone DMA32), il est donc généralement d'environ 16 Mo.

Commit du code Linux

mm :redimensionne les filigranes kswapd proportionnellement à la mémoire

[…]

watermark_scale_factor :

Ce facteur contrôle l'agressivité de kswapd. Il définit la
quantité de mémoire restante dans un nœud/système avant que kswapd ne soit réveillé et
la quantité de mémoire devant être libérée avant que kswapd ne se remette en veille.

L'unité est en fractions de 10 000. La valeur par défaut de 10 signifie que les
distances entre les filigranes sont de 0,1 % de la mémoire disponible dans le
nœud/système. La valeur maximale est 1 000, soit 10 % de la mémoire.

Un taux élevé de threads entrant en récupération directe (allocstall) ou kswapd
passant en veille prématurément (kswapd_low_wmark_hit_quickly) peut indiquer
que le nombre de pages libres que kswapd maintient pour des raisons de latence est
trop petit pour le rafales d'allocation se produisant dans le système. Ce bouton
peut ensuite être utilisé pour ajuster l'agressivité de kswapd en conséquence.

proc :meminfo :estime la mémoire disponible de manière plus prudente

Le MemAvailable élément dans /proc/meminfo est de donner aux utilisateurs une indication de la
quantité de mémoire pouvant être allouée sans provoquer d'échange, de sorte qu'il exclut
les marques d'eau basses des zones comme indisponibles pour l'espace utilisateur.

Cependant, pour une allocation d'espace utilisateur, kswapd récupérera en fait
jusqu'à ce que les pages libres atteignent une combinaison de la limite supérieure et de la
protection lowmem de l'allocateur de pages qui conserve également une certaine quantité de mémoire DMA
et DMA32 de l'espace utilisateur.

Soustrayez le montant total que nous savons être indisponible pour l'espace utilisateur du
nombre de pages gratuites lors du calcul de MemAvailable.

Code Linux

On prétend parfois que changer swappiness à désactivera efficacement "l'échange opportuniste". Cela offre une piste d'investigation intéressante. S'il y a quelque chose appelé "échange opportuniste", et qu'il peut être réglé par swappiness, alors nous pourrions le rechercher en trouvant toutes les chaînes d'appel qui lisent vm_swappiness . Notez que nous pouvons réduire notre espace de recherche en supposant CONFIG_MEMCG n'est pas défini (c'est-à-dire que les "groupes de contrôle de mémoire" sont désactivés). La chaîne d'appel va :

  • vm_swappiness
  • mem_cgroup_swappiness
  • get_scan_count
  • shrink_node_memcg
  • shrink_node
En relation :Quel PATH utilise `sudo ` pour rechercher `` ?

shrink_node_memcg est commenté "Il s'agit d'une page de base par nœud plus libre. Utilisé à la fois par kswapd et la récupération directe ». C'est à dire. cette fonction augmente le nombre de libres pages. Il n'essaie pas de dupliquer des pages pour les échanger afin qu'elles puissent être libérées beaucoup plus tard. Mais même si nous ne tenons pas compte de cela :

La chaîne ci-dessus est appelée à partir de trois fonctions différentes, illustrées ci-dessous. Comme prévu, nous pouvons diviser les sites d'appel en récupération directe vs. kswapd. Cela n'aurait aucun sens d'effectuer un "échange opportuniste" en récupération directe.

  1. /*
     * This is the direct reclaim path, for page-allocating processes.  We only
     * try to reclaim pages from zones which will satisfy the caller's allocation
     * request.
     *
     * If a zone is deemed to be full of pinned pages then just give it a light
     * scan then give up on it.
     */
    static void shrink_zones
    
  2.  * kswapd shrinks a node of pages that are at or below the highest usable
     * zone that is currently unbalanced.
     *
     * Returns true if kswapd scanned at least the requested number of pages to
     * reclaim or if the lack of progress was due to pages under writeback.
     * This is used to determine if the scanning priority needs to be raised.
     */
    static bool kswapd_shrink_node
    
  3.  * For kswapd, balance_pgdat() will reclaim pages across a node from zones
     * that are eligible for use by the caller until at least one zone is
     * balanced.
     *
     * Returns the order kswapd finished reclaiming at.
     *
     * kswapd scans the zones in the highmem->normal->dma direction.  It skips
     * zones which have free_pages > high_wmark_pages(zone), but once a zone is
     * found to have free_pages <= high_wmark_pages(zone), any page in that zone
     * or lower is eligible for reclaim until at least one usable zone is
     * balanced.
     */
    static int balance_pgdat
    

Donc, on peut supposer que l'affirmation est que kswapd est réveillé d'une manière ou d'une autre, même lorsque toutes les allocations de mémoire sont satisfaites immédiatement à partir de la mémoire libre. J'ai regardé à travers les utilisations de wake_up_interruptible(&pgdat->kswapd_wait) , et je ne vois aucun réveil comme celui-ci.


Linux
  1. Utilisation de la mémoire Linux

  2. Comment supprimer les tampons de mémoire et le cache sous Linux

  3. Linux - Détermination correcte de l'utilisation de la mémoire sous Linux ?

  4. Commande gratuite sous Linux expliquée avec des exemples

  5. Linux effectue-t-il des échanges opportunistes ou est-ce un mythe ?

Commande gratuite Linux (vérifier l'utilisation de la mémoire)

Commande gratuite sous Linux

Linux Oom au hasard alors qu'il y a encore de la mémoire libre ?

Comment fonctionne la mémoire d'échange sous Linux ?

exemples de commandes gratuits sous Linux

Trouver la taille de la RAM sous Linux