2015-06-12 10 views
5

İstemci-sunucu bağlantılarını desteklemesi gereken bir uygulama üzerinde çalışıyorum. Bunu yapmak için, WebSockets oluşturmama izin veren tornado modülünü kullanıyorum. Her zaman operasyonda, en azından sunucu tarafında olmak niyetindeyim. Bu nedenle, bu bağlantılarda oluşturulan nesnelerin her birinin performans ve bellek kullanımı konusunda çok endişeliyim. Gerçekten bu nesnelerin kütüphane tarafından ne zaman ortadan kaldırıldığını tespit etmek için test yapmaya başladım. Örnek kodu almak ve yöntem __del__()python - WebSocketHandler ve TornadoWebSocketClient ne zaman tamamen silinir?

server.py

#! /usr/bin/env python 
import tornado.httpserver 
import tornado.websocket 
import tornado.ioloop 
import tornado.web 
import gc, sys 
import resource 

class WSHandler(tornado.websocket.WebSocketHandler): 
    def open(self): 
     print 'new connection' 
     self.write_message("h") 

    def check_origin(self, origin): 
     return True 

    def on_message(self, message): 
     print "Message: " + message 

    def on_close(self): 
     print 'Closed' 
     print 'GC count: ' + str(len(gc.get_referrers(self))) 

    def __del__(self): 
     print "DELETED" 

application = tornado.web.Application([ 
    (r'/s', WSHandler), 
]) 


if __name__ == "__main__": 
    http_server = tornado.httpserver.HTTPServer(application) 
    http_server.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 

client.py müşteri mesajı alır

#! /usr/bin/env python 
from ws4py.client.tornadoclient import TornadoWebSocketClient 
from tornado import ioloop 

class MainClient(TornadoWebSocketClient): 
    def opened(self): 
     print "Connected" 

    def received_message(self, message): 
     print "Message" 

     #I close the connection 
     self.close() 

    def closed(self, code, reason=None): 
     print "Closed" 
     ioloop.IOLoop.instance().stop() 

    def __del__(self): 
     print "DELETED" 

if __name__ == "__main__": 
    ws = MainClient('ws://localhost:8888/s', protocols=['http-only', 'chat']) 
    ws.connect() 

    ioloop.IOLoop.instance().start() 

overwrote , bu bağlantıyı kapatır. Bağlantı kapatıldığı ve bu nedenle __del__() yöntemini çağırdığı için her iki nesnenin de elendiğini umuyordum, ancak bu olmadı.

sunucu çıkışı:

new connection 
Closed 
GC count: 6 

istemci çıkışı:

Connected 
Message 
Closed 

bunu ben __del__() yönteminden bekliyordum DELETED cümleyi yazdırmak vermedi görebileceğiniz gibi. --edited--

da bir bağlantı kapama sırasında nesnenin GC sahip referans numarasını koyar hattı ekledik. Bu gerçekten referans döngüleri olduğunu kanıtlıyor.

-----

O daha karmaşık olacaktır kullanmak, ama gerçekten bilmek aradığını hem nesnelerin davranışını anlamak için bana yardımcı olacak Açıkçası sınıfları: zaman silindi mi Onları çıkarırken belleği boşaltır mı? ya da bir şekilde oluyor? veya the nesneyi açıkça nasıl silebilirim?

tornado.websocket.WebSocketHandlerdocumentation'u okudum, nesne "kapalı" olduğunda beni açıklar, ancak belleğin ne zaman çıktığını bilmiyorum.

cevap

3

WebSocket kodu şu anda bazı referans döngüleri içerir, bu da nesnelerin bir sonraki tam GC'ye kadar temizlenmediği anlamına gelir. Daha da kötüsü, __del__ yöntemleri aslında bir nesnenin silinmesini engelleyebilir (python 3.3 ve daha eski sürümlerde: https://docs.python.org/3.3/library/gc.html#gc.garbage), bu yüzden şeylerin gerçekten silindiğini söylemek zor. Bunun yerine, sadece sisteminizi test etmeli ve bellek ayak izinin zamanla arttığını görmelisiniz.

+0

bu referans döngülerini önlemek için (bir bağlantıdan sonra başvuru çevreleri kırmaya Yamalar hoş olurdu kapalıdır), olurdu 'bir seçenek weakref'? Ya da beyaz yapmak için bir şey yok? –

+1

Zayıf akımın geçerli GC'deki döngülerle yardımcı olup olmadığından emin değilim (zayıf referanslar içeren bir döngü hala döngüdür).Bu durumda, bazı açık temizleme kodlarımız var (IOStream'i kapattığımız ve işleyiciyi IOLoop'tan kaldıracağımız), bu yüzden sadece bir döngüye neden olabilecek (ve artık gerekmediği) özelliklerin Hiçbiri olarak ayarlanmamasını sağlamaya ihtiyacımız var. . –