我有一个Twisted客户端应用程序,每分钟可以建立数百个连接。我发现我的应用程序有内存泄漏,我几乎可以肯定它与永不删除的ClientFactory()派生类有关。
我通过修改Twisted文档中的Echo客户端示例来重现该问题:
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from sys import stdout
class Echo(Protocol):
def connectionMade(self):
print 'MADE'
self.transport.write('XXXX')
def dataReceived(self, data):
print 'RECV', data
self.transport.loseConnection()
def __del__(self):
print 'DEL PROTOCOL'
class EchoClientFactory(ClientFactory):
def startedConnecting(self, connector):
print 'Started to connect.'
def buildProtocol(self, addr):
print 'Connected.'
return Echo()
def clientConnectionLost(self, connector, reason):
print 'Lost connection. Reason:', reason
def clientConnectionFailed(self, connector, reason):
print 'Connection failed. Reason:', reason
def __del__(self):
print 'DEL FACTORY'
def connector():
print 'CONNECTOR'
factory = EchoClientFactory()
reactor.connectTCP('localhost', 7, factory)
#reactor.callLater(2, connector)
register_loop = LoopingCall(connector)
register_loop.start(1)
reactor.run()
使用此代码,我发现只有在程序关闭时才会删除EchoClientFactory()的实例。连接完成后不会删除它们。我没有在文档中找到我是否需要做一些来删除工厂实例。
答案 0 :(得分:1)
在协议和工厂中添加__del__
方法使它们无法收集。请参阅gc.garbage
列表。在此示例中,此列表将永远增长。如果删除__del__
方法,问题就会消失。在我的64位Ubuntu 12.04机器上,该客户端的常驻内存使用率稳定在13MB。