python-WebSocketHandler和WebSocketClient何时被完全删除?

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

我正在开发一个必须支持客户机-服务器连接的应用程序。为了做到这一点,我正在使用tornado模块,它允许我创建WebSocket。我打算一直运行,至少在服务器端。因此,我非常担心在这些连接上创建的每个对象的性能和内存使用情况。 我已经开始做测试来检测库何时消除了这些对象。 以示例代码为例,我重写了方法
\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。