Я работаю над приложением, которое должно поддерживать соединения клиент-сервер. Для этого я использую модуль торнадо, который позволяет мне создавать WebSockets. Я намерен всегда работать, по крайней мере, на стороне сервера. Поэтому меня очень беспокоит производительность и использование памяти каждого из объектов, созданных в этих соединениях. Я начал выполнять тесты, чтобы определить, когда эти объекты будут уничтожены библиотекой. Возьмем пример кода, и я переписал метод __del__()
python - Когда полностью удалены WebSocketHandler и TornadoWebSocketClient?
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
#! /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()
Когда клиент получает сообщение, он закрывает соединение. Я надеялся, что оба объекта были устранены, потому что соединение было закрыто, поэтому вызовите метод __del__()
, но этого не произошло. Выход сервера
: выход
new connection
Closed
GC count: 6
клиента:
Connected
Message
Closed
Как вы можете видеть, что это не напечатать DELETED
фразы, что я ожидал от метода __del__()
.
--edited--
Также я добавил строку, которая выводит количество ссылок, которое имеет GC этого объекта в момент закрытия соединения. Это доказывает, что существуют действительно циклы ссылок.
-----
Очевидно, что классы, которые я буду использовать будет более сложным, чем те, но помочь мне понять поведение обоих объектов, что является то, что я на самом деле стремятся знать: когда они удалены? Это освобождает память при удалении их? или каким-то иным образом? или ¿как удалить объект явно?
Я читал tornado.websocket.WebSocketHandler
documentation, он объясняет мне, когда объект «закрыт», но я не знаю, когда будет выпущена память.
Чтобы избежать этих опорных циклов, будет 'weakref' варианта? Или нечего делать? –
Я не уверен, что «weakref» помогает с циклами в текущем GC (цикл, включающий слабые ссылки, по-прежнему является циклом).В этом случае у нас уже есть явный код очистки (где мы закрываем IOStream и удаляем обработчик из IOLoop), поэтому нам просто нужно убедиться, что любые атрибуты, которые могут вызвать цикл (и больше не нужны), установлены на None , –