1

我正在编写一个脚本,它打开一个文本文件并循环遍历每一行(每行之间暂停几秒钟)。对于每一行,它都会打开一个瞬态客户端套接字连接并将文本发送到主机服务器。主机响应可能会或可能不会出现;无论哪种方式都没关系。

我已经遇到了 Python 套接字限制,您无法重新连接现有的套接字对象(因为这样做会触发异常EBADF, 'Bad file descriptor')。所以我正在为每个瞬态连接创建一个新的套接字实例。那么诀窍当然就是如何避免内存泄漏。

我解决这个问题的方法是将创建、使用和关闭套接字的整个部分推送到一个函数——在我完成后依靠 Python 的垃圾收集来删除每个实例:

    导入套接字,选择,时间

    def 瞬态连接(主机、端口、发送数据):
        响应 = ''
        sendSocket = socket.socket()
        sendSocket.connect((serverHost,serverPort))
        sendSocket.send(线)
        gotData = select.select([sendSocket],[],[],2)
        if (gotData[0]):response = sendSocket.recv(65535)
        sendSocket.close()
        返回响应

    scriptLines = open('testScript.txt','r').readlines()
    服务器主机 = '127.0.0.1'
    服务器端口 = 15004
    对于 scriptLines 中的行:
        响应 = 瞬态连接(服务器主机、服务器端口、线路)
        打印(响应)
        时间.sleep(3.0)

我的问题:(1)这种方法可以避免任何内存泄漏吗?(2) 是否有更直接的方法来确保在我完成后消除每个实例?

4

1 回答 1

4

首先,一次交换只使用一个套接字是正常的。请参阅套接字 HOWTO

python 的优点之一是通常您不必担心垃圾收集。除非你有真正的内存使用问题,否则你不应该这样做。

此网页中,请记住:

“当对象超出范围时,Python 不会清理它。当对它的最后一个引用超出范围时,它会清理它。”

因此,如果在函数内部创建的套接字没有在其他地方引用,它应该超出范围并被释放(但不是 gc-ed)。以下内容可能特定于 cpython。阅读文档以gc.set_threshold()了解垃圾收集在 cpython 中的工作原理。尤其:

“当分配数减去解除分配数超过threshold0时,收集开始。”

阈值的标准值(在 cpython 中)是:

In [2]: gc.get_threshold()
Out[2]: (700, 10, 10)

所以在你运行 gc 之前会有相当数量的分配。您可以通过运行强制垃圾收集gc.collect()

于 2012-12-29T14:06:18.543 回答