2010-09-17 9 views
5

Ich benutze Cherrypy in einem RESTful Web-Service und Server gibt XML als Ergebnis zurück (Lxml wird verwendet, um XML zu erstellen). Einige dieser XML-Dateien sind ziemlich groß. Ich habe bemerkt, dass Speicher nicht freigegeben wird, nachdem eine solche Anfrage (die Rückgabe von großem XML) verarbeitet wurde.Speicherverbrauch in Cherrypy

Also, ich habe ein Problem isoliert und diese sehr kurzes Blind Beispiel erstellt:

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()) 

Nach Anfrage wurde gemacht: http://localhost:8080/index, Speicherverbrauch geht von 830MB bis 1,2 GB. Dann, nachdem die Anfrage bearbeitet wurde, geht sie auf 1,1 GB herunter und bleibt dort, bis der Server heruntergefahren wird. Nach dem Herunterfahren des Servers sinkt der Speicherverbrauch auf 830 MB.

In meinem Projekt stammen Daten (natürlich) aus der Datenbank, und Parameter werden verwendet, um anzugeben, welche Daten abgerufen werden sollen. Wenn dieselbe Anfrage (mit denselben Parametern) gemacht wird, bleibt der Speicher bei 1,1 GB, d. H. Es wird kein zusätzlicher Speicher verwendet. Wenn jedoch verschiedene Parameter übergeben werden, verbraucht der Server immer mehr Speicher. Die einzige Möglichkeit, den Speicher freizugeben, besteht darin, den Server neu zu starten.

Haben Sie irgendwelche Ideen, warum dies geschieht und wie Sie es lösen können? Vielen Dank.

+0

Welche Betriebssystem verwenden Sie? – unutbu

+0

Ich benutze Ubuntu. Der Grund, warum ich auf die Freigabe von Speicher eifrig war, ist die Tatsache, dass die Datenbank weit über 100 GB groß ist. Da der Server mehr und mehr läuft, gibt es mehr unterschiedliche Anfragen, was dazu führt, dass mehr Speicher verwendet wird. Meine Sorge war, was passiert, wenn dieser Speicherverbrauch der physischen Speichergröße nahe kommt? Kann Python den Speicher, den er gerade hält (aber nicht benutzt), wiederverwenden, wenn neue Anfragen kommen? Ich nehme ja an, wollte aber nur nachsehen. Was ist, wenn es andere Prozesse gibt, die Speicher benötigen? Welche Erinnerung werden sie verwenden? – kevin

Antwort

1

Dies ist ein generisches Python-Problem, nicht wirklich ein CherryPy an sich. effbot hat eine große Antwort auf diese Frage bei http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

Und es gibt eine ähnliche SO mit einer großen Antwort auf Frage bei How can I explicitly free memory in Python?

+0

Ich verstehe. Vielen Dank für die Antwort. Was passiert, wenn der Speicherverbrauch dem physischen Speicherlimit nahe kommt und eine neue Anfrage eingeht? Wird Python wissen, wie man Speicher wiederverwenden kann, den dieser Prozess hält, aber nicht benutzt? Was passiert mit anderen Prozessen, die Speicher benötigen? Sollte ich hier Prozesse statt Threads verwenden? Mit der Zeit wird dieser Server mehr und mehr Speicher belegen (da verschiedene Anfragen kommen). Gibt es einen Moment, in dem Python diesen belegten (aber nicht benutzten) Speicher wiederverwenden wird, oder wird er nur den Speicher abarbeiten und Swap benutzen? – kevin

+1

Ja, Python wird Speicher wiederverwenden. Andere Prozesse, die Speicher beanspruchen, konkurrieren dafür, normalerweise vom Betriebssystem moderiert. Achten Sie auf den "OOM Killer" in Linux OS. Threads sind ein Gerät, das den Speicherverbrauch im Vergleich zu Prozessen teilen und damit * reduzieren *. Und schließlich, ja, Swap wird die ganze Zeit verwendet. Lesen Sie Ihre BS-Dokumente. – fumanchu