2010-09-17 18 views
5

RESTful web hizmetinde Cherrypy kullanıyorum ve sunucu sonucu XML olarak döndürüyor (XML oluşturmak için lxml kullanılıyor). Bu XML'lerden bazıları oldukça büyüktür. Böyle bir istek (büyük XML döndüren) işlendikten sonra belleğin yayınlanmadığını fark ettim.Cherrypy'de Bellek Tüketimi

Yani, bir sorunu izole edilmiş ve bu bir çok kısa kukla örneğini oluşturduk: http://localhost:8080/index bellek tüketimi 1.2GB için 830MB gider: İsteğe sonra

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

yapılmamıştır. Daha sonra, istek işlendikten sonra 1.1GB'ye düşecek ve sunucu kapatılana kadar orada kalacaktır. Sunucu kapatıldıktan sonra, bellek tüketimi 830MB'ye düşer.

Projemde, veri (tabii ki) veri tabanından geliyor ve hangi verilerin alınacağını belirlemek için parametreler kullanılıyor. Aynı talep (aynı parametrelerle) yapılırsa, bellek 1.1GB'da kalır, yani ilave hafıza kullanılmaz. Ancak, farklı parametreler geçilirse, sunucu daha fazla bellek tüketmeye devam eder. Belleği boşaltmanın tek yolu sunucuyu yeniden başlatmaktır.

Bunun neden olduğu ve nasıl çözüleceği konusunda herhangi bir fikriniz var mı? Teşekkürler.

+0

büyük bir cevabı olan soru var? – unutbu

+0

Ubuntu kullanıyorum. Belleğin açığa çıkarılmasının sebebi, veri tabanının 100GB'ın üzerinde olması. Sunucu gittikçe arttıkça, daha fazla belleğin kullanıldığı daha farklı istekler vardır. Endişem, bu hafıza tüketimi fiziksel bellek boyutuna yaklaştığında ne olacağıydı? Python, yeni talepler geldiğinde o andaki belleğin nasıl kullanılacağını (ancak kullanılmayan) nasıl kullanacağını biliyor mu? Evet, ama kontrol etmek istedim. Ayrıca, bellek talep eden başka süreçler varsa ne olur? Hangi belleği kullanacaklar? – kevin

cevap

1

Bu, genel olarak bir CherryPy değil, genel bir Python sorundur. effbot http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

bu soruya iyi bir cevap var Ve benzer SO sen hangi işletim sistemini kullanıyorsunuz How can I explicitly free memory in Python?

+0

Anladım. Cevabınız için çok teşekkürler. Bellek tüketimi fiziksel bellek limitine yaklaştığında ve yeni istek geldiğinde ne olur? Python, işlemin tuttuğu ama kullanmadığı belleği nasıl yeniden kullanacağını biliyor mu? Hafıza talep eden diğer süreçlere ne olacak? Burada iş parçacığı yerine süreçleri kullanmayı düşünmeli miyim? Zamanla bu sunucu daha fazla bellek işgal edecektir (farklı istek gelecektir). Python'un bu işgal edilen (ama kullanılmayan hafıza) yeniden kullanılmaya başlayacağı bir an mı var, yoksa sadece hafızamızı mı çalıştıracak ve takas kullanmaya başlayacak mı? – kevin

+1

Evet, Python belleği yeniden kullanacaktır. Bellek gerektiren diğer işlemler, genellikle işletim sistemi tarafından yönetilen, bunun için rekabet edecektir. Linux işletim sistemindeki "OOM katili" ye dikkat edin. İş parçacıkları, paylaşılacak ve dolayısıyla bellek tüketimini * işlemlere göre * azaltan bir cihazdır. Ve son olarak, evet, takas her zaman kullanılır. OS belgelerinizi okuyun. – fumanchu