2010-09-17 15 views
5

J'utilise Cherrypy dans un service Web RESTful et le serveur renvoie XML en conséquence (lxml est utilisé pour créer XML). Certains de ces XML sont assez volumineux. J'ai noté que la mémoire n'est pas libérée après qu'une telle demande (que le grand XML de retour) ait été traitée.Consommation de mémoire dans Cherrypy

Alors, j'ai isolé un problème et a créé ce un exemple fictif très court:

import cherrypy 
from lxml import etree 

class Server: 
    @cherrypy.expose 
    def index(self): 
     foo = etree.Element('foo') 
     for i in range(200000): 
      bar = etree.SubElement(foo, 'bar') 
      bar1 = etree.SubElement(bar, 'bar1') 
      bar1.text = "this is bar1 text ({0})".format(i) 
      bar2 = etree.SubElement(bar, 'bar2') 
      bar2.text = "this is bar2 text ({0})".format(i) 
      bar3 = etree.SubElement(bar, 'bar3') 
      bar3.text = "this is bar3 text ({0})".format(i) 
      bar4 = etree.SubElement(bar, 'bar4') 
      bar4.text = "this is bar4 text ({0})".format(i) 
      bar5 = etree.SubElement(bar, 'bar5') 
      bar5.text = "this is bar5 text ({0})".format(i) 

     return etree.tostring(foo, pretty_print=True) 

if __name__ == '__main__': 
    cherrypy.quickstart(Server()) 

Après la demande a été faite à: http://localhost:8080/index, la consommation de mémoire passe de 830MB à 1.2GB. Ensuite, après que la demande a été traitée, elle descend à 1,1 Go et reste là jusqu'à ce que le serveur soit arrêté. Après l'arrêt du serveur, la consommation de mémoire descend à 830 Mo.

Dans mon projet, les données (bien sûr) proviennent de la base de données, et les paramètres sont utilisés pour spécifier quelles données doivent être récupérées. Si la même requête (avec les mêmes paramètres) est effectuée, la mémoire reste à 1,1 Go, c'est-à-dire qu'aucune mémoire supplémentaire n'est utilisée. Mais, si différents paramètres sont passés, le serveur consomme de plus en plus de mémoire. Le seul moyen de libérer de la mémoire est de redémarrer le serveur.

Avez-vous des idées sur la raison pour laquelle cela se produit et comment le résoudre? Merci.

+0

Quel système d'exploitation utilisez-vous? – unutbu

+0

J'utilise Ubuntu. La raison pour laquelle j'avais hâte à la libération de mémoire est le fait que la base de données est bien plus de 100Go. Comme le serveur s'exécute de plus en plus, il y a plus de demandes différentes qui résultent de l'utilisation de plus de mémoire. Mon inquiétude était ce qui va se passer quand cette consommation de mémoire se rapproche de la taille physique de la mémoire? Python saura-t-il réutiliser la mémoire qu'il tient actuellement (mais qui n'est pas utilisée) lorsque de nouvelles requêtes arrivent? Je présume oui, mais je voulais juste vérifier. Aussi, et s'il y a d'autres processus qui sont en demande de mémoire? Quel souvenir vont-ils utiliser? – kevin

Répondre

1

Ceci est un problème générique de Python, pas vraiment un CherryPy en soi. effbot a une excellente réponse à cette question à http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

Et il y a une même question si une grande réponse à How can I explicitly free memory in Python?

+0

Je vois. Merci beaucoup pour la réponse. Que se passe-t-il lorsque la consommation de mémoire se rapproche de la limite de mémoire physique et qu'une nouvelle requête intervient? Python saura-t-il réutiliser la mémoire que le processus tient mais n'utilise pas? Qu'adviendra-t-il des autres processus en demande de mémoire? Dois-je envisager d'utiliser des processus au lieu de threads ici? Avec le temps ce serveur occupera de plus en plus de mémoire (car une requête différente viendra). Y a-t-il un moment où Python commencera à réutiliser cette mémoire occupée (mais non utilisée) ou bien il va simplement utiliser notre mémoire et commencer à utiliser swap? – kevin

+1

Oui, Python réutilisera la mémoire. D'autres processus qui demandent de la mémoire seront en concurrence pour cela, modérés par le système d'exploitation habituellement. Cherchez le "OOM Killer" dans Linux OS. Les threads sont un périphérique à partager et donc à * réduire * la consommation de mémoire par rapport aux processus. Et enfin, oui, swap est utilisé tout le temps. Lisez vos documents d'OS. – fumanchu