8

我在 python 脚本中有一个(明显的)内存泄漏,我无法完全解释(常驻内存不断增长)。它从大约 6MB 的驻留开始,我让它运行了一夜,它已经超过了 200MB(我这样做是为了排除由于 gc 导致的锯齿状内存使用模式)。我把它浓缩成这个脚本:

import sys
import time
import paramiko

def update():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(hostname='localhost')
    finally:
        ssh.close()

def main():
    while(True):
        update()
        time.sleep(0.001)

if __name__ == '__main__':
    sys.exit(main())

我认为问题可能是我不断实例化一个新的 SSHClient 并且它们并没有被抛出,但是这个版本更快地泄漏内存!

import sys
import time
import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
def update():
    global ssh
    try:
        ssh.connect(hostname='localhost')
    finally:
        ssh.close()

def main():
    while(True):
        update()
        time.sleep(0.001)

if __name__ == '__main__':
    sys.exit(main())

如果有人可以对此有所了解,或者如果我只是愚蠢并且有人可以指出为什么我会非常感激。谢谢

4

3 回答 3

4

我设法重现。调查时,我发现很可能泄漏与 libssl 相关,因为分配量在增长

前:

35aaa53000-35aaa5b000 rw-p 00053000 00:11 3360939                        /usr/lib64/libssl.so.1.0.0j
...
7f4530000000-7f453013b000 rw-p 00000000 00:00 0 
Size:               1260 kB
Rss:                1012 kB
Pss:                1012 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:      1012 kB
Referenced:         1012 kB
Anonymous:          1012 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
7f453013b000-7f4534000000 ---p 00000000 00:00 0 
Size:              64276 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB

一段时间后:

35aaa53000-35aaa5b000 rw-p 00053000 00:11 3360939                        /usr/lib64/libssl.so.1.0.0j
...
7f4530000000-7f4530250000 rw-p 00000000 00:00 0 
Size:               2368 kB
Rss:                2120 kB
Pss:                2120 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:      2120 kB
Referenced:         2120 kB
Anonymous:          2120 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
7f4530250000-7f4534000000 ---p 00000000 00:00 0 
Size:              63168 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB

似乎是 libssl 或 paramiko 本身的错误,因为 gc.garbage 是空的并且 len(gc.get_objects()) 是恒定的,这意味着没有牢不可破的循环并且没有新的 python 对象(使用您的第一个版本)。

顺便说一句,您可以在每次迭代时运行 gc.collect() 以避免锯齿。

于 2013-01-05T07:57:04.833 回答
1

似乎至少有其他用户最近在 Paramiko 的 IRC 上遇到了这个问题;我创建了一张票来跟踪它:https ://github.com/paramiko/paramiko/issues/182 - 遗憾的是我没有智慧分享自己,因为这一级别的问题不是我有故障排除经验的问题。

于 2013-07-07T17:56:23.403 回答
0

这些天我遇到了同样的问题。我认为这是lib的错误。同时你的用法不正确。关键问题是您没有定义密钥文件。根据 AutoAddPolicy 源代码:

 def missing_host_key(self, client, hostname, key):
        client._host_keys.add(hostname, key.get_name(), key)
        if client._host_keys_filename is not None:

您可以将策略处理程序更改为 WarningPolicy 或自己定义一个空句柄。如:

class DoNothingPolicy ():
    def missing_host_key(self, client, hostname, key):
        pass
于 2016-08-30T03:16:43.853 回答