10
votes

Python Memory FootPrint Vs. Taille du tas

Je reçois des problèmes de mémoire lors de l'utilisation d'un script Python pour émettre une grande requête forte> Solr forte>. J'utilise la bibliothèque forte> Solrpy forte> à l'interface avec le serveur SOLR. La requête renvoie environ 80 000 enregistrements. Immédiatement après la délivrance de la requête L'empreinte de la mémoire Python telle que visualisée à travers les ballons supérieurs à ~ 190 Mo. xxx pré>

à ce stade, le profil de démarrage tel que visualisé via le tas ressemble à celui-ci: p>

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 8225 root      16   0  195m 192m 3432 S  0.0 11.3   0:13.46 python
...


2 commentaires

Ce comportement est-il reproductible pour des requêtes plus petites aussi?


L'empreinte de la mémoire physique augmente proportionnellement à la taille de la requête.


4 Réponses :


5
votes

Python attribue des objets Unicode du tas C. Donc, lorsque vous allouez beaucoup d'entre eux (avec d'autres blocs MALLOC), alors libérez la plupart d'entre eux, à l'exception du dernier, C MALLOC ne retournera aucune mémoire au système d'exploitation, car le tas de C rétrécira uniquement à la fin ( pas au milieu). Libérant le dernier objet Unicode libérera le bloc à la fin de la prise C, qui permet ensuite à Malloc de rentrer tout au système.

En plus de ces problèmes, Python maintient également un pool d'objets UNICODE libérés pour une allocation plus rapide. Ainsi, lorsque le dernier objet Unicode est libéré, il n'est pas retourné à Malloc immédiatement, rendant toutes les autres pages bloquées.


3 commentaires

Juste pour clarifier, vous dites que la sortie du tas indique le contenu du tas de python privé. La sortie supérieure indique la mémoire totale allouée à mon processus via l'API C? Si tel est le cas, pouvez-vous suggérer des techniques de manière à garantir que Python libère la mémoire brute sur le système d'exploitation une fois que le contenu de cette mémoire n'est plus nécessaire?


Comme Roberto dit: utilisez la dernière version Python. Si le problème ne disparaît pas, signalez un bug sur des bugs.python.org, de préférence comprenant un correctif.


Il semble que Python sur Linux ne libère pas la mémoire libérée du système d'exploitation. Plus d'infos ici: python.dzone.com/articles/diagness-memory-leaks- Python



1
votes

Quelle version de Python utilisez-vous?
Je vous demande parce que Version ancienne de CPPHON n'a pas libéré la mémoire et ceci a été corrigé à Python 2.5 .


3 commentaires

J'utilisais CPPHON 2.4 lorsque je suis tombé sur le lien que vous avez posté. Malheureusement, je rencontre le même comportement lorsque j'exécute les scripts en 2.6.


Êtes-vous sûr que vous utilisez la version mise à jour? J'ai eu un problème similaire une fois et j'ai découvert que le serveur utilisait toujours une version plus ancienne de Python.


Je cours sur une machine Centos où 2.4 est la version par défaut. J'ai installé 2.6 juste pour tester ce problème. Je gère mes scripts appelant explicitement python2.6.



2
votes

CPPHON Mise en œuvre uniquement de la mémoire allouée d'une gratuité exceptionnelle. Il s'agit d'un bug largement connu, mais cela ne reçoit pas beaucoup d'attention par les développeurs CPPHON. La solution de contournement recommandée est de "fourchette et de mourir" le processus qui consomme beaucoup de RAM.


3 commentaires

Est-ce que le bogue que Roberto fait référence à celui-ci a été corrigé en 2.5? Ou ce bogue est-il connu pour exister encore?


Hruske, es-tu vraiment sûr de ce que vous dites? Je n'ai aucune expérience de ce bogue, et je n'ai également aucune connaissance de celui-ci du suivi de l'insecte Python.


De mon expérience, oui. Par exemple, le traitement de grandes quantités de données dans une DAMON vous laissera ensuite avec une grande quantité de RAM Malloc'd, qui sera ensuite échancrée et très probablement pas libre. Cependant, cela peut ne pas être dû à un virus GC, mais plutôt à cause d'une référence circulaire. Essayez de vérifier ici lshift.net/blog/2008/11 / 14 / Tracing-Python-Memory-Fuites Si cela aide.



0
votes

J'ai mis en œuvre les conseils de «fourchette et meurez» de Hruske. J'utilise OS.FORK () pour exécuter la section intensive de mémoire du code dans un processus enfant, puis je laisse le processus enfant sortir. Le processus parent exécute un OS.WAITPID () sur l'enfant afin qu'un seul thread est exécutant à un moment donné.

Si quelqu'un voit des pièges avec cette solution, veuillez vous aider.


1 commentaires

Os.fork () peut être désordonné dans des applications multi-threadées. Fourchette "Duplicate" Toute la mémoire du processus, mais ne conserve que le fil principal en cours d'exécution. Donc, tout verrou que vous avez entré dans d'autres threads, vous pourriez empêcher votre application forcée.