L'utilisation de la mémoire rapportée par guppy diffèrent de commande ps
-
20-09-2019 - |
Question
Je profilage mon serveur torsadé. Il utilise beaucoup plus de mémoire que prévu. Son utilisation de la mémoire se développe au fil du temps.
ps -o pid,rss,vsz,sz,size,command
PID RSS VSZ SZ SZ COMMAND
7697 70856 102176 25544 88320 twistd -y broadcast.tac
Comme vous pouvez le voir coûts 102176 KBS , à savoir, 99.78125 MBs . Et j'utilise guppy d'un trou d'homme tordu pour regarder le profil d'utilisation de la mémoire.
>>> hp.heap()
Partition of a set of 120537 objects. Total size = 10096636 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 61145 51 5309736 53 5309736 53 str
1 27139 23 1031596 10 6341332 63 tuple
2 2138 2 541328 5 6882660 68 dict (no owner)
3 7190 6 488920 5 7371580 73 types.CodeType
4 325 0 436264 4 7807844 77 dict of module
5 7272 6 407232 4 8215076 81 function
6 574 0 305776 3 8520852 84 dict of class
7 605 1 263432 3 8784284 87 type
8 602 0 237200 2 9021484 89 dict of type
9 303 0 157560 2 9179044 91 dict of zope.interface.interface.Method
<384 more rows. Type e.g. '_.more' to view.>
Hum ... Il semble qu'il y ait quelque chose de mal. Guppy montre que l'utilisation totale de la mémoire est 10096636 octets, à savoir 9859.996 KBS ou 9.628 MBs .
C'est une énorme différence. Quel est le problème ce résultat étrange? Qu'est-ce que je fais mal?
Mise à jour: J'ai écrit un script de contrôle hier soir. Il enregistre l'utilisation de la mémoire et le nombre d'utilisateurs en ligne. Il est un serveur de radio, de sorte que vous pouvez voir qu'il ya des radios et des auditeurs au total. Voici la figure I résultant de matplotlib.
Quelque chose est étrange. Parfois, l'utilisation de la mémoire imprimée par ps est très faible, comme celui-ci
2010-01-15 00:46:05,139 INFO 4 4 17904 36732 9183 25944
2010-01-15 00:47:03,967 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:48:04,373 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:49:04,379 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:50:02,989 INFO 4 4 3700 5256 1314 2260
Quelle est la raison de la valeur de super faible utilisation de la mémoire? Et en plus, même il n'y a pas de radio en ligne, pas d'auditeurs, l'utilisation de la mémoire est encore élevé.
La solution
peut-être dû à la permutation / réservation de mémoire, en fonction de la définition de ps:
RSS: resident set size, the non-swapped physical memory
that a task has used (in kiloBytes).
VSZ: virtual memory usage of entire process.
vm_lib + vm_exe + vm_data + vm_stack
il peut être un peu déroutant, 4 paramètres de différentes tailles peuvent être vus avec:
# ps -eo pid,vsz,rss,sz,size,cmd|egrep python
PID VSZ RSS SZ SZ CMD
23801 4920 2896 1230 1100 python
la taille virtuelle comprend une mémoire qui a été réservée par le processus et non utilisé, la taille de toutes les bibliothèques partagées qui ont été chargés, les pages qui sont permutées et des blocs qui ont déjà été libérés par votre processus, il pourrait être beaucoup plus que la taille de tous les objets en direct en python.
quelques outils supplémentaires pour enquêter sur les performances de la mémoire:
-
Heapy (partie de Guppy, que vous utilisez): http://guppy-pe.sourceforge.net/
-
Python Memory Validator http://www.softwareverify.com/python/memory/index.html
-
PySizer http://pysizer.8325.org/
bon guide sur traquer les fuites de mémoire en python utilisant pdb et objgraph:
http://www.lshift.net/ blog / 2008/11/14 / traçage-la mémoire des python fuites
Autres conseils
Comme indiqué ci-dessus la taille de RSS est ce que vous êtes le plus intéressé par ici. La taille « virtuelle » comprend des bibliothèques cartographiés, que vous ne voulez probablement pas compter.
Il a été un moment que je heapy, mais je suis assez sûr que les statistiques qu'elle imprime ne comprennent pas les frais généraux ajoutés par heapy lui-même. Cette surcharge peut être assez important (je l'ai vu un processus de 100MB RSS croître une douzaine d'autres MB, voir http://www.pkgcore.org/trac/pkgcore/doc/dev-notes/heapy.rst ).
Mais dans votre cas, je soupçonne que le problème est que vous utilisez une bibliothèque C qui soit des fuites ou utilise la mémoire d'une manière qui heapy ne suit pas. Heapy est au courant de la mémoire utilisée directement par des objets python, mais si ces objets englobent les objets C qui sont attribués séparément heapy ne sont pas normalement au courant de cette mémoire du tout. Vous pourrez peut-être ajouter le support heapy à vos fixations (mais si vous ne contrôlez pas les liaisons que vous utilisez c'est évidemment embêtant, et même si vous ne contrôlez les liaisons que vous ne pouvez pas être en mesure de le faire en fonction de ce que vous envelopper ).
En cas de fuites au niveau heapy C également perdre la trace de cette mémoire (taille RSS monteront mais la taille de heapy rapportée restera le même). Valgrind est probablement votre meilleur pari pour suivre ces bas, tout comme il est dans d'autres applications C.
Enfin: la fragmentation de la mémoire souvent la cause de votre utilisation de la mémoire (comme on le voit en haut) pour monter, mais pas vers le bas (beaucoup). Ceci est généralement pas beaucoup d'un problème avec daemons, puisque le processus réutiliser cette mémoire, il est tout simplement pas remis à l'os, de sorte que les valeurs en haut ne reviennent pas vers le bas. Si l'utilisation de la mémoire (comme on le voit par dessus) monte plus ou moins linéairement avec le nombre d'utilisateurs (connexions), ne va pas vers le bas, mais aussi ne pas garder de plus en plus à jamais jusqu'à ce que vous atteignez un nouveau nombre maximum d'utilisateurs, la fragmentation est probablement à blâmer.
Ce n'est pas une réponse complète, mais de votre trou d'homme, je voudrais aussi vous suggérons de lancer manuellement GC.Collect () avant la recherche avec ps ou en haut. guppy montrera le tas alloué, mais ne fait rien à des objets de manière proactive libre qui ne sont plus affectées.