Tôi đang làm việc trên một ứng dụng phải hỗ trợ các kết nối máy khách-máy chủ. Để làm được điều đó, tôi đang sử dụng mô-đun lốc xoáy cho phép tôi tạo WebSockets. Tôi dự định sẽ luôn hoạt động, ít nhất là phía máy chủ. Vì vậy, tôi rất lo lắng về hiệu suất và mức sử dụng bộ nhớ của từng đối tượng được tạo trên các kết nối này. Tôi đã bắt đầu làm các xét nghiệm để phát hiện khi thực sự các đối tượng này bị loại bỏ bởi thư viện. Lấy mã ví dụ và tôi ghi đè lên các phương pháp __del__()
python - Khi nào WebSocketHandler và TornadoWebSocketClient hoàn toàn bị xóa?
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()
Khi khách hàng nhận được một tin nhắn, nó đóng kết nối. Tôi hy vọng rằng cả hai đối tượng đã bị loại bỏ, bởi vì kết nối đã được đóng lại, và do đó gọi phương thức __del__()
, nhưng điều đó đã không xảy ra.
sản lượng máy chủ: sản lượng
new connection
Closed
GC count: 6
khách hàng:
Connected
Message
Closed
Như bạn có thể nhìn thấy nó không in DELETED
câu mà tôi đã mong đợi từ các phương pháp __del__()
.
--edited--
Ngoài ra tôi đã thêm dòng in số lượng tài liệu tham khảo trong đó có các GC của đối tượng đó tại thời điểm đóng kết nối. Điều này chứng minh rằng có thực sự tham khảo chu kỳ.
-----
Rõ ràng là các lớp học mà tôi sẽ sử dụng sẽ phức tạp hơn so với những người, nhưng giúp tôi hiểu được hành vi của cả hai đối tượng, đó là những gì tôi thực sự tìm cách biết: khi họ có bị xóa không? Nó giải phóng bộ nhớ khi xóa chúng? hoặc bằng cách nào đó trở thành bằng cách nào đó? hoặc ¿cách xóa đối tượng một cách rõ ràng?
Tôi đọc số tornado.websocket.WebSocketHandler
documentation, nó giải thích cho tôi khi đối tượng bị "đóng", nhưng tôi không biết khi nào bộ nhớ được giải phóng.
Để tránh những chu kỳ tài liệu tham khảo, sẽ được 'weakref' một lựa chọn? Hoặc không có gì để làm whit nó? –
Tôi không chắc liệu 'weakref' có giúp các chu trình trong GC hiện tại hay không (một chu trình bao gồm các tham chiếu yếu vẫn là một chu kỳ).Trong trường hợp này, chúng tôi đã có một số mã dọn dẹp rõ ràng (nơi chúng tôi đóng IOStream và xóa trình xử lý khỏi IOLoop), vì vậy chúng tôi chỉ cần đảm bảo rằng bất kỳ thuộc tính nào có thể gây ra chu kỳ (và không còn cần thiết) được đặt thành Không . –