Qu'est-ce qui a utilisé la mémoire Linux? Cache faible, tampon faible, pas une machine virtuelle

11

Tout d'abord, oui, j'ai lu LinuxAteMyRAM , ce qui n'explique pas ma situation.

# free -tm
             total       used       free     shared    buffers     cached
Mem:         48149      43948       4200          0          4         75
-/+ buffers/cache:      43868       4280
Swap:        38287          0      38287
Total:       86436      43948      42488
#

Comme indiqué ci-dessus, la -/+ buffers/cache:ligne indique que le taux de mémoire utilisé est très élevé. Cependant, à partir de la sortie de top, je ne vois aucun processus utilisé plus de 100 Mo de mémoire.

Alors, qu'est-ce qui a utilisé la mémoire?

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
28078 root      18   0  327m  92m  10m S    0  0.2   0:25.06 java
31416 root      16   0  250m  28m  20m S    0  0.1  25:54.59 ResourceMonitor
21598 root     -98   0 26552  25m 8316 S    0  0.1  80:49.54 had
24580 root      16   0 24152  10m  760 S    0  0.0   1:25.87 rsyncd
 4956 root      16   0 62588  10m 3132 S    0  0.0  12:36.54 vxconfigd
26703 root      16   0  139m 7120 2900 S    1  0.0   4359:39 hrmonitor
21873 root      15   0 18764 4684 2152 S    0  0.0  30:07.56 MountAgent
21883 root      15   0 13736 4280 2172 S    0  0.0  25:25.09 SybaseAgent
21878 root      15   0 18548 4172 2000 S    0  0.0  52:33.46 NICAgent
21887 root      15   0 12660 4056 2168 S    0  0.0  25:07.80 SybaseBkAgent
17798 root      25   0 10652 4048 1160 S    0  0.0   0:00.04 vxconfigbackupd

Il s'agit d'une machine x86_64 (pas un serveur de marque commune) exécutant x84_64 Linux, pas un conteneur dans une machine virtuelle. Noyau ( uname -a):

Linux 2.6.16.60-0.99.1-smp #1 SMP Fri Oct 12 14:24:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

Contenu de /proc/meminfo:

MemTotal:     49304856 kB
MemFree:       4066708 kB
Buffers:         35688 kB
Cached:         132588 kB
SwapCached:          0 kB
Active:       26536644 kB
Inactive:     17296272 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:     49304856 kB
LowFree:       4066708 kB
SwapTotal:    39206624 kB
SwapFree:     39206528 kB
Dirty:             200 kB
Writeback:           0 kB
AnonPages:      249592 kB
Mapped:          52712 kB
Slab:          1049464 kB
CommitLimit:  63859052 kB
Committed_AS:   659384 kB
PageTables:       3412 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    478420 kB
VmallocChunk: 34359259695 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

dfne signale aucune grande consommation de mémoire des tmpfssystèmes de fichiers.

Jason
la source
2
Quelle est la sortie de ps -eo pid,user,args,pmem --sort pmem?
Braiam
Collé ici, lien , essayé quelques fois, a obtenu la même sortie.
Jason
3
Ne pas utiliser head! Je veux la sortie complète de la commande complete. Si je voulais que vous l'utilisiez, headje le mettrais dans ma commande. Veuillez toujours fournir la sortie complète à la commande demandée par les utilisateurs.
Braiam
3
Sur un téléphone, ne me souviens pas de la syntaxe du haut de ma tête, mais vérifiez la mémoire partagée sysv. La commande est ipcs, je pense.
derobert
5
Avez-vous déjà trouvé une solution pour cela? - J'ai un problème similaire ici: superuser.com/questions/793192/…
Hackeron

Réponses:

4

La mémoire sous Linux peut être une étrange bête à diagnostiquer et à comprendre.

En fonctionnement normal, la plupart, sinon la totalité, de votre mémoire sera allouée à une tâche ou à une autre. Certains seront alloués aux processus de premier plan en cours d'exécution. Certains stockeront des données mises en cache à partir du disque. Certains contiendront des données associées à des processus qui ne s'exécutent pas activement à ce moment précis.

Un processus sous Linux possède son propre espace d'adressage virtuel (VIRT dans la sortie de top). Celui-ci contient toutes les données associées au processus et peut être considéré comme la «taille» du processus. Cependant, il est rare que toute cette mémoire fasse activement partie de la "vraie" carte mémoire (RES dans la sortie de top). Le RES, ou mémoire résidente, est les données qui sont directement accessibles dans la RAM à un moment donné. Ensuite, il y a aussi la mémoire partagée (SHR) en plus de cela. Cela peut être partagé entre plusieurs instances du même processus. Ainsi, la mémoire utilisée par un processus est à n'importe quel moment dans le temps RES plus SHR, mais s'il y a plus d'une instance du processus utilisant la mémoire partagée, l'utilisation est RES plus RES plus RES ... plus SHR.

Alors pourquoi la différence entre RES et VIRT? Certes, si un processus a un bloc de mémoire alloué, c'est de la mémoire allouée, n'est-ce pas? Non. La mémoire est allouée en pages et les pages peuvent être actives ou inactives. Les actifs sont ceux qui sont dans RES. Les autres sont inactifs. Ils peuvent être poussés d'un côté car ils ne sont pas accessibles pour le moment. Cela signifie qu'ils peuvent être échangés sur le disque si la mémoire est saturée. Mais ils ne vont pas directement sur le disque. D'abord, ils sont assis dans une cache. Vous ne voulez pas échanger tout le temps, il y a donc un tampon entre l'application et l'espace d'échange. Ces tampons changent constamment lorsque le swapper sélectionne un processus différent à exécuter et différentes pages deviennent actives et inactives. Et tout ce qui se passe de manière à jeûner pour un simple humain à suivre.

Et en plus de tout cela, il y a les tampons de disque. Non seulement la mémoire inactive va dans un cache, mais lorsque ce cache est échangé sur le disque, il va d'abord dans un tampon de disque pour être mis en file d'attente pour l'écriture. Voilà donc une deuxième couche de cache dans le mélange. Et ces tampons de disque sont également utilisés par d'autres parties du système pour la mise en mémoire tampon générale des E / S. Ils changent donc constamment aussi.

Donc, ce que vous voyez dans des choses comme topet freeetc., ce sont soit des instantanés instantanés de l'état actuel de la machine, soit des statistiques agrégées sur une période de temps. Au moment où vous avez lu les données, elles sont obsolètes.

Tout processus peut accéder à de grandes quantités de mémoire, mais il est rarement judicieux de le faire. De toute façon, il ne peut pas accéder à toute la mémoire, donc la mémoire qu'elle ne regarde pas actuellement est déplacée dans le cache à moins qu'elle ne soit spécifiquement signalée comme étant "verrouillée dans le cœur".

Ainsi, la quantité de mémoire "utilisée" par une application et la quantité de mémoire qu'elle "possède" sont deux choses complètement différentes. Une grande partie de l'espace de données des applications se trouve en fait dans le cache, pas dans la mémoire "principale", mais comme le cache est dans la mémoire RAM la plupart du temps, il est instantanément disponible et a juste besoin d'être "activé" pour devenir une mémoire "principale". C'est à moins qu'il n'ait été échangé sur le disque, lorsqu'il a alors besoin d'être annulé (ce qui peut être rapide s'il est dans le tampon).

En raison de la nature à grande vitesse de la bête et du fait que les chiffres changent toujours, les chiffres peuvent même changer à mi-chemin en calculant ce qu'ils sont, il n'est donc jamais possible de dire exactement "c'est combien de mémoire est utilisée" à partir de le point de vue d'un utilisateur. Le meminfo est un instantané dans le temps fourni par le noyau, mais comme c'est le noyau qui s'exécute, il ne montre pas nécessairement l'état réel de l'un des processus d'utilisation de la mémoire, car aucun processus ne s'exécute activement à ce moment-là - c'est entre les processus.

Comme je l'ai dit, tout cela est très déroutant.

Mais à la fin de la journée, cela n'a vraiment pas d'importance. Ce qui importe n'est pas la quantité de mémoire disponible, mais la quantité d'espace de swap que vous avez utilisée et la fréquence d'accès à l'espace de swap. C'est l'échange qui ralentit un système, pas le manque de mémoire (bien que le manque de mémoire entraîne un échange excessif). Si vous avez beaucoup de mémoire utilisée, mais que vous n'utilisez pas (ou très peu) d'espace de swap, alors les choses sont normales. La mémoire libre en général n'est pas souhaitable, et est souvent purement transitoire de toute façon, en ce sens qu'elle était utilisée dans un but, mais n'a pas encore été allouée pour une autre - par exemple, c'était de la mémoire cache, et elle a été échangée sur le disque, mais il n'a pas encore été utilisé pour autre chose, ou c'était des tampons de disque, les tampons ont été vidés sur le disque, mais aucune application ne l'a encore demandé pour le cache.

Majenko
la source
6
Ceci est vraiment intéressant mais ne répond pas à la question de savoir pourquoi le PO observe cette divergence spécifique.
terdon
Je pense que la seule vraie différence se situe entre les attentes des OP et ce que Linux fournit. C'est-à-dire que les valeurs que Linux donne ne s'additionnent pas, et c'est parce qu'elles ont déjà changé.
Majenko
Comme le PO ne semble pas vraiment comprendre la question qu'il pose, je ne vois pas comment une «bonne» réponse peut être choisie. Nous pouvons expliquer comment le système fonctionne jusqu'à ce que nous soyons bleus, mais s'il ne parvient pas à saisir ces bases et à se rendre compte que sa question n'a en fait aucun sens, nous n'aurons jamais de «bonne» réponse.
Majenko
J'apprécie d'avoir écrit cela, mais honnêtement, je n'aime pas le ton agnostique qui se cache derrière. Je suis d'accord avec la théorie du "snapshot" mais si le snapshot continue de donner le même nombre qui indique que l'utilisation de la RAM est élevée alors que vous ne pouvez pas savoir comment cela s'est produit, ne serez-vous pas curieux?
Jason
5
Vous devriez poster ceci sur votre blog. C'est bien, mais ce n'est pas pertinent ici. Il se passe quelque chose de bizarre (et je veux dire de bizarre venant de quelqu'un qui comprend ce que vous avez écrit), car les processus VIRT ne tiennent pas compte de toute l'utilisation de la RAM et le système ne change pas malgré les pressions pour le faire.
Gilles 'SO- arrête d'être méchant'
0

Ceci est une partie de la réponse:

Il y a une différence entre ce qui est désigné comme mémoire "utilisée" (dans la commande "libre") et "Mémoire allouée aux processus (utilisateur) actifs" (dans / proc / meminfo). Ok, donc votre système a un total de 48149 Mo (environ 47 Go)

Si vous regardez votre / proc / meminfo, vous voyez: Inactif: 17296272 ko = (environ 16,5 Go) - La mémoire inactive peut provenir de processus qui se sont terminés. Il peut également s'agir d'une mémoire qui n'a pas été utilisée depuis longtemps par un processus actif. La mémoire n'est pas "libérée" simplement parce que le processus s'est terminé. Pourquoi? parce que c'est plus de travail. La même page de mémoire peut être utilisée à nouveau, de sorte que le noyau Linux laisse simplement les données sur la liste "inactive" jusqu'à ce qu'un processus en ait besoin.

Cette page explique une partie de cela. http://careers.directi.com/display/tu/Understanding+and+optimizing+Memory+utilization ; Lisez la section sur le PFRA (algorithme de récupération de cadre de page) utilisé par le noyau Linux: "Les pages incluses dans les caches de disque et de mémoire qui ne sont référencées par aucun processus doivent être récupérées avant que les pages appartenant aux espaces d'adressage en mode utilisateur des processus" "Récupération" signifie les faire sortir de "utilisé" (inactif + actif) et devenir "libre".

Cela explique la gestion de la mémoire plus en détail: comment fonctionnent les listes actives et inactives et comment les pages se déplacent entre elles https://www.cs.columbia.edu/~smb/classes/s06-4118/l19.pdf

Je crois qu'il y a aussi de la mémoire utilisée par le noyau pour les structures de données, et que cela apparaît comme "slab 1049464 kb" (~ 1 Go) je crois, mais je ne suis pas certain que cela soit compté séparément.

ssl
la source
Je voulais juste ajouter que dans le passé, j'avais de l'expérience avec un système manquant de mémoire en raison d'une application mal écrite qui allouait des segments de mémoire partagée, mais ne les libérait pas. Les segments de mémoire partagée ont persisté même lorsque tous les processus les utilisant sont morts. Ce n'était pas Linux, mais cela pourrait aussi être vrai sous Linux. comme mentionné ci-dessus, voir ipcs pour plus d'informations à ce sujet. voir makelinux.net/alp/035 Il indique que vous devez explicitement désallouer la mémoire partagée.
ssl
1
Je ne comprends pas tout sur quoi porte votre réponse, mais «la mémoire inactive pourrait provenir de processus qui se sont terminés» est définitivement faux. La mémoire Userland est disponible en deux versions: mappée ou anonyme. La mémoire mappée peut toujours être récupérée car les données peuvent être rechargées à partir d'un fichier. La mémoire anonyme peut être récupérée si elle est échangée. La mémoire inactive est une mémoire qui est un bon candidat pour la récupération; cependant, le contenu doit se trouver dans un fichier ou être échangé quelque part, car cette mémoire est toujours utilisée. Lorsqu'un processus meurt, sa mémoire devient libre et n'est plus comptabilisée en actif + inactif.
Gilles 'SO- arrête d'être méchant'
1
Quelques références: Qu'est - ce qui peut provoquer une augmentation de la mémoire inactive et comment la récupérer? sur panne de serveur; des conseils anciens mais toujours applicables de Red Hat . Et l'article de Bhavin Turakhia que vous citez également; ce n'est pas explicite à ce sujet, mais cela explique les pages anonymes et mappées dans la section «Comprendre l'ARAP».
Gilles 'SO- arrête d'être méchant'
J'ai eu la pensée sur les pages inactives non référencées par un processus de cet article: kernel.org/doc/gorman/html/understand/understand013.html Bien que je suppose que cela pourrait être des pages libérées par un processus qui est toujours en cours d'exécution. section "Récupération des pages des listes LRU"
ssl
Mais peut-être que cela fait simplement référence aux pages du cache de swap?
ssl
-2

Utilisez-vous NFS?
Cela vaut peut-être la peine de courir dans les slabtop -odeux sens, cela nfs_inode_cachepeut devenir incontrôlable.

cjve
la source
-4

Le chiffre que vous devriez regarder est utilisé swap , dans votre sortie qui est "0" ce qui signifie que vous n'avez PAS à court de RAM. Tant que votre système n'échange pas de mémoire, vous ne devez pas vous soucier des autres chiffres, qui sont de toute façon très difficiles à interpréter.

Edit: Ok, il semble que ma réponse soit considérée comme cryptique plutôt que concise. Alors laissez-moi développer.

Je suppose que le principal problème ici est d'interpréter la sortie de top / ps, qui n'est pas très précise. Par exemple, comme plusieurs utilisations des mêmes bibliothèques partagées ne sont pas calculées comme vous vous y attendez, voir par exemple http://virtualthreads.blogspot.ch/2006/02/understanding-memory-usage-on-linux.html

Ce qui est cependant très précis, c'est que si la taille du swap est exactement nulle, alors votre système n'a pas (encore) manqué de mémoire. Bien sûr, c'est une déclaration très bien sûr, mais pour profiler l'utilisation réelle de la mémoire de votre système, top ne sera pas la bonne chose. (Et si vous regardez en haut, triez au moins la sortie pour virt ou% mem.)

Voir aussi http://elinux.org/Runtime_Memory_Measurement

Echsecutor
la source
1
Vous ne devriez pas vous inquiéter non plus si votre système échange, c'est normal. Vous devriez vous inquiéter si votre système échange trop souvent (ce qui n'est pas la même chose que d'avoir un grand espace d'échange utilisé). Le fait que le swap utilisé soit 0 est en soi bizarre, avec si peu de mémoire physique libre.
Gilles 'SO- arrête d'être méchant'
eh bien, sa sortie indique que son système n'a pas échangé du tout. C'est sûrement le taux d'échange optimal. Je n'ai pas dit qu'une petite taille de swap est une bonne chose, mais une taille nulle l'est certainement. Et tant que le système ne manque pas de mémoire libre, pourquoi devrait-il commencer à échanger?
Echsecutor
Non, l'absence d'échange est loin d'être optimale. La mémoire des programmes qui ne sont pas utilisés actuellement doit être permutée pour faire de la place au cache disque pour les fichiers fréquemment utilisés. En ce qui concerne le bit que vous venez d'ajouter sur la sortie de free, je pense que vous vouliez dire top- mais même alors, la somme ne peut être supérieure au total (car la mémoire partagée est comptée plusieurs fois), pas moins.
Gilles 'SO- arrête d'être méchant'
que voulez-vous dire par la somme ne peut être plus ni moins? le haut ne montre que le nombre de processus à l'écran, je suis sûr que ce qui précède n'est pas tous les processus en cours d'exécution, donc ils ne sont pas triés par utilisation de la mémoire, ce morceau de sortie est assez inutile pour la question `` ce qui a utilisé la mémoire '' .
Echsecutor
oh, et je ne veux pas entrer dans un débat pour savoir quand le moment optimal pour commencer à échanger est, mais la valeur par défaut du serveur linux est de ne pas échanger de mémoire uniquement parce qu'il "ne s'habitue pas pour le moment".
Echsecutor