无法找到内存泄漏(tracemalloc / objgraph / gc无效)

时间:2019-05-15 17:48:27

标签: python-3.x memory-leaks

我有一个网络进程,该进程通过TCP进行通信,以收集数据,将其反序列化并最终将其部分存储在LevelDB键/值存储中(通过Plyvel)。

随着时间的流逝,它将消耗所有可用内存,直至整个系统锁定(Ubuntu 18.04)。我正在尝试诊断原因,但是用尽了如何进一步调查的想法。

我想到的主要怀疑对象是我们用来反序列化对象的数据流。在那里完成的一般操作是:从asyncio.StreamReader接收数据并调用deserialize_from_bytes(请参见下一个)

    @classmethod
    def deserialize_from_bytes(cls, data_stream: Union[bytes, bytearray]):
        """ Deserialize object from a byte array. """
        br = BinaryReader(stream=data_stream)
        inv_payload = cls()
        try:
            inv_payload.deserialize(br)
        except ValueError:
            return None
        finally:
            br.cleanup()
        return inv_payload

BinaryReader的初始化方式如下

   def __init__(self, stream: Union[io.BytesIO, bytes, bytearray]) -> None:
        super(BinaryReader, self).__init__()

        if isinstance(stream, (bytearray, bytes)):
            self._stream = io.BytesIO(stream)
        else:
            self._stream = stream

cleanup()self._stream.close()

的便捷包装

我尝试过的事情

  1. 我首先尝试了tracemalloc的{​​{3}}代码段。在/proc/$mypid/status的内存使用量为2GB(由VmSize表示)的时间点上,tracemalloc中消耗最大的项仅报告了38MB,其次是第二个和第三个是3MB, 360Kb。

    这已经引起了一个问题;其他〜1.958 GB在哪里?

  2. 我尝试display top 10的上述输出没有帮助。我使用pdb进入了流程,并使用

import objgraph
objgraph.show_most_common_types(limit=20)

获得

function                   16451
tuple                      11456
dict                       10371
weakref                    3058
list                       2893
cell                       2446
Traceback                  2277
Statistic                  2277
_Binding                   2109
getset_descriptor          1814
type                       1680
builtin_function_or_method 1469
wrapper_descriptor         1311
method_descriptor          1284
frozenset                  992
property                   983
module                     810
ModuleSpec                 808
SourceFileLoader           738
Attrs                      593

在该列表中我没有看到任何特定于我的程序的对象(这可能表示未释放引用)。在其他objgraph实例中,我发现上述计数似乎与众不同。我检查了两个function对象,并始终发现与此类似的东西(与异步有关),这并不表示有任何暗示。内存在那里泄漏

(Pdb) objgraph.at(0x10f309b70)
<function _run_coroutine.<locals>.step_next.<locals>.continue_ at 0x10f309b70>

如果我缺少一些东西,请在这里纠正我。再次,没有进一步的步骤

  1. 最后尝试看看我是否可以强制执行任何释放的内存,我手动运行objgraph。反复调用它会为不可达对象的数量提供25-500之间的值。它不会触发我的问题(应该吗?)。我还尝试过使用gc.set_debug(gc.DEBUG_LEAK)运行该程序,但这产生了太多的输出,我什么都做不了。

有什么提示可以从这里开始尝试吗?

0 个答案:

没有答案