0

我有一个长期运行的 Python 项目,它的内存使用量缓慢但持续增加。如果主脚本需要处理大量工作并且主进程和子进程都在无限运行(或者直到删除目标作业),则主脚本会设置新进程(使用多处理)。

为了尝试了解内存泄漏的来源,我使用该guppy模块来分析我的内存,然后让每个进程每两分钟将内存配置文件写入一个文件。

在检查内存配置文件时,我看到只有一种类型的内存在增加 - list。其余类型中的值基本上是静态的(有时高一点,有时低一点)。

例如,以下是其中一个流程的报告:

 Index  Count   %     Size   % Cumulative  % Referrers by Kind (class / dict of class)
     0   3707  43   491717  58    491717  58 list
     1   4200  48   239659  28    731376  87 dict of CustomClass
     2    600   7    96000  11    827376  98 CustomClass
     3      4   0     4646   1    832022  98 _io.TextIOWrapper
     4     40   0     3664   0    835686  99 dict (no owner)
     5     46   1     3358   0    839044  99 urllib.parse.SplitResult
     6     90   1     2160   0    841204 100 dict of OtherCustomClass
     7     18   0     2080   0    843284 100 tuple
     8      1   0      424   0    843708 100 <Nothing>
     9      4   0      384   0    844092 100 types.FrameType

如果任何其他类型的内存数量或大小会增加,我可能会告诉哪个列表是内存泄漏的罪魁祸首,但因为只是list大小增加,我不确定我应该如何处理并找到哪个列表是泄漏的来源。

此外,我所有属于类实例的列表要么受大小限制,要么每个间隔都被清除(并且我确保调用了 clear )。我在函数内部创建的其他列表,我希望一旦它们不再在范围内就会被删除。

我错过了什么吗?非常感谢

4

1 回答 1

0

考虑使用https://github.com/vmware/chap

在您的情况下,您可能需要执行以下操作:

开始您的流程(不以任何方式检测)。

为该过程获取实时核心,例如通过使用 gcore,相距足够远以显示增长。

对于每个核心,在 chap 中打开核心并执行以下操作:

redirect on
describe used

因此,您将拥有两个文件(每个内核一个),您可以比较它们以查看哪些分配是新的或已消失的。您的列表应该反映在那里。找到其中一个列表的地址并使用“解释”来弄清楚它是如何使用的。

于 2020-09-24T12:52:42.517 回答