python - WebSocketHandler和TornadoWebSocketClient何时完全删除?

Dav*_*dez 5 python object tornado websocket

我正在开发一个必须支持客户端 - 服务器连接的应用程序.为了做到这一点,我正在使用龙卷风模块,允许我创建WebSockets.我打算一直在运作,至少在服务器端.所以我非常担心在这些连接上创建的每个对象的性能和内存使用情况.我已经开始做测试,以检测库实际消除这些对象的时间.以示例代码为例,我覆盖了该方法__del__()

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()
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

当客户端收到消息时,它会关闭连接.我希望两个对象都被删除,因为连接已关闭,所以调用__del__()方法,但是没有发生.

服务器输出:

new connection
Closed
GC count: 6
Run Code Online (Sandbox Code Playgroud)

客户输出:

Connected
Message
Closed
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它没有打印出DELETED我期望从该__del__()方法中得到的句子.

--edited--

此外,我添加了一行,用于打印在关闭连接时具有该对象的GC的引用数.这证明确实存在参考周期.

-----

显然我将使用的类将比那些更复杂,但帮助我理解两个对象的行为,这是我真正想要知道的:它们什么时候被删除?删除它时释放内存?或以其他方式成为某种方式 或¿如何明确删除对象?

我阅读了tornado.websocket.WebSocketHandler 文档,它解释了我什么时候对象"关闭",但我不知道什么时候内存被释放.

Ben*_*ell 3

WebSocket 代码当前包含一些引用循环,这意味着直到下一次 Full GC 才会清理对象。更糟糕的是,__del__方法实际上可以防止删除对象(在 python 3.3 及更早版本中:https://docs.python.org/3.3/library/gc.html#gc.garbage ://docs.python.org/3.3/library/gc.html#gc.garbage ),因此很难判断事情何时发生实际上被删除了。相反,您只需要对系统进行负载测试,看看其内存占用量是否会随着时间的推移而增加。

(欢迎在连接关闭后打断引用循环的补丁)