2015-06-12 7 views
5

मैं ऐसे एप्लिकेशन पर काम कर रहा हूं जो क्लाइंट-सर्वर कनेक्शन का समर्थन करे। ऐसा करने के लिए, मैं टर्ननाडो के मॉड्यूल का उपयोग कर रहा हूं जो मुझे वेबसाकेट बनाने की अनुमति देता है। मैं कम से कम सर्वर-साइड ऑपरेशन में हमेशा रहने का इरादा रखता हूं। इसलिए मैं इन कनेक्शनों पर बनाए गए प्रत्येक ऑब्जेक्ट के प्रदर्शन और स्मृति उपयोग के बारे में बहुत चिंतित हूं। मैंने पुस्तकालय द्वारा वास्तव में इन वस्तुओं को समाप्त करने के दौरान परीक्षण करने के लिए परीक्षण करना शुरू कर दिया है। उदाहरण कोड ले लो और मैं विधि __del__()पायथन - 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--

इसके अलावा, मैं लाइन है कि जो कनेक्शन बंद करने के समय में उस वस्तु की जीसी है सन्दर्भ की संख्या प्रिंट जोड़ दिया है। यह साबित करता है कि वास्तव में संदर्भ चक्र हैं।

-----

जाहिर वर्गों है कि मैं का उपयोग उन लोगों की तुलना में अधिक जटिल हो जाएगा होगा, लेकिन मुझे दोनों वस्तुओं के व्यवहार है, जो कि मैं क्या सच में जानना चाहते हैं है समझने में मदद: जब क्या वे हटा दिए गए हैं? जब उन्हें हटाते हैं तो यह स्मृति को मुक्त करता है? या अन्यथा किसी भी तरह से बन रहे हैं? या ¿वस्तु को स्पष्ट रूप से कैसे हटाएं?

मैंने tornado.websocket.WebSocketHandlerdocumentation पढ़ा, यह मुझे बताता है कि ऑब्जेक्ट "बंद" है, लेकिन मुझे नहीं पता कि स्मृति कब जारी की जाती है।

उत्तर

3

वेबसाकेट कोड में वर्तमान में कुछ संदर्भ चक्र हैं, जिसका अर्थ है कि वस्तुओं को अगले पूर्ण जीसी तक साफ़ नहीं किया जाता है। इससे भी बदतर, __del__ विधियां वास्तव में किसी ऑब्जेक्ट को हटाने (पाइथन 3.3 और पुराने: https://docs.python.org/3.3/library/gc.html#gc.garbage में) को रोक सकती हैं, इसलिए यह कहना मुश्किल है कि चीजें वास्तव में कब हटाई जा रही हैं। इसके बजाए, आपको बस अपने सिस्टम का परीक्षण लोड करना होगा और देखें कि समय के साथ इसकी मेमोरी पदचिह्न बढ़ जाती है या नहीं।

+0

उन संदर्भ चक्र से बचने के लिए (पैच एक कनेक्शन के बाद संदर्भ चक्र को तोड़ने के लिए स्वागत किया जाएगा बंद कर दिया है), होगा 'एक विकल्प weakref'? या इसे करने के लिए कुछ भी नहीं है? –

+1

मुझे यकीन नहीं है कि मौजूदा जीसी में चक्रों के साथ 'कमजोर' मदद करता है (कमजोर संदर्भ सहित एक चक्र अभी भी एक चक्र है)।इस मामले में हमारे पास पहले से ही कुछ स्पष्ट सफाई कोड है (जहां हम IOStream को बंद करते हैं और IOLoop से हैंडलर को हटाते हैं), इसलिए हमें यह सुनिश्चित करने की आवश्यकता है कि कोई भी विशेषता जो चक्र का कारण बन सकती है (और अब इसकी आवश्यकता नहीं है) किसी को भी सेट नहीं किया गया है । –

संबंधित मुद्दे