İ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.WebSocketHandler
documentation'u okudum, nesne "kapalı" olduğunda beni açıklar, ancak belleğin ne zaman çıktığını bilmiyorum.
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? –
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. . –