python-WebSocketHandler和WebSocketClient何时被完全删除?
我正在开发一个必须支持客户机-服务器连接的应用程序。为了做到这一点,我正在使用tornado模块,它允许我创建WebSocket。我打算一直运行,至少在服务器端。因此,我非常担心在这些连接上创建的每个对象的性能和内存使用情况。 我已经开始做测试来检测库何时消除了这些对象。 以示例代码为例,我重写了方法python-WebSocketHandler和WebSocketClient何时被完全删除?,python,object,websocket,tornado,Python,Object,Websocket,Tornado,我正在开发一个必须支持客户机-服务器连接的应用程序。为了做到这一点,我正在使用tornado模块,它允许我创建WebSocket。我打算一直运行,至少在服务器端。因此,我非常担心在这些连接上创建的每个对象的性能和内存使用情况。 我已经开始做测试来检测库何时消除了这些对象。 以示例代码为例,我重写了方法\uu del\uu() server.py #! /usr/bin/env python import tornado.httpserver import tornado.websocket im
\uu del\uu()
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()
当客户端收到消息时,它会关闭连接。我希望这两个对象都被删除,因为连接已关闭,因此调用\uu del\uu()
方法,但这没有发生
服务器输出:
new connection
Closed
GC count: 6
客户端输出:
Connected
Message
Closed
正如您所看到的,它没有打印我所期望的\uu del\uuu()
方法中的已删除的
句子
--编辑--
此外,我还添加了一行,用于打印在关闭连接时具有该对象GC的引用数。这证明确实存在引用循环
----
显然,我将使用的类比那些类更复杂,但是帮助我理解这两个对象的行为,这是我真正想要知道的:它们何时被删除?删除它们时会释放内存吗?或者以其他方式变得不一样?或者如何明确删除对象
我阅读了
tornado.websocket.WebSocketHandler
,它解释了对象何时“关闭”,但我不知道内存何时释放。websocket代码当前包含一些引用周期,这意味着对象在下一次完全GC之前不会被清理。更糟糕的是,\uuu del\uu
方法实际上可以阻止删除对象(在python 3.3和更早版本中:),因此很难判断什么时候实际删除了对象。相反,您只需要对系统进行负载测试,看看它的内存占用是否会随着时间的推移而增加
(欢迎在连接关闭后使用修补程序中断引用周期)要避免这些引用周期,是否可以选择
weakref
?或者与此无关?我不确定weakref
是否有助于当前GC中的循环(包括弱引用的循环仍然是一个循环)。在本例中,我们已经有了一些明确的清理代码(在这里我们关闭IOStream并从IOLoop中删除处理程序),因此我们只需要确保任何可能导致循环(不再需要)的属性都设置为None。