长时间运行的 Python 程序(使用 Pandas)不断增加内存使用量

Posted

技术标签:

【中文标题】长时间运行的 Python 程序(使用 Pandas)不断增加内存使用量【英文标题】:Long-running Python program (using Pandas) keeps ramping up memory usage 【发布时间】:2019-12-18 11:02:39 【问题描述】:

我正在运行一个 python 脚本,该脚本在无限循环中使用 Pandas 函数处理和处理数据。但随着时间的推移,该程序似乎正在泄漏内存。

这是由 memory-profiler 包生成的图表:

遗憾的是,我无法确定内存使用量增加的原因。据我所知,所有数据(pandas 时间序列)都存储​​在对象Obj 中,我使用pandas 函数.memory_usage 和objsize 函数get_deep_size() 跟踪该对象的内存使用情况。根据他们的输出,内存使用量应该稳定在 90-100 MB 左右。除此之外,我看不出内存可以在哪里增加。

知道 python 程序在 docker 容器中运行可能很有用。

下面是脚本的简化版本,它应该阐明基本的工作原理。

from datetime import datetime
from time import sleep
import objsize
from dateutil import relativedelta

def update_data(Obj, now_utctime):
    # attaining the newest timeseries data
    new_data = requests.get(host, start=Obj.data[0].index, end=now_utctime)
    Obj.data.append(new_data)

    # cut off data older than 1 day
    Obj.data.truncate(before=now_utctime-relativedelta.relativedelta(days=1))

class ExampleClass():
    def __init__(self):
        now_utctime = datetime.utcnow()
        data = requests.get(host, start=now_utctime-relativedelta.relativedelta(days=1), end=now_utctime)

Obj = ExampleClass()

while True:
    update_data(Obj, datetime.utcnow())
    logger.info(f"Average at datetime.utcnow() is at Obj.data.mean()")
    logger.info(f"Stored timeseries memory usage at Obj.data.memory_usage(deep=True)* 10 ** -6 MB")
    logger.info(f"Stored Object memory usage at objsize.get_deep_size(Obj) * 10 ** -6 MB")
    time.sleep(60)

任何关于内存可以增加的地方或如何进一步调查的建议,我们将不胜感激。

编辑:查看图表,在我截断之前会有峰值是有道理的,但由于数据入口是稳定的,我不知道为什么它不会正常化,但仍然存在在更高的点。然后每第 4 个周期后就会出现这种突然下降,即使该过程没有另一个更广泛的周期可以解释这一点……

【问题讨论】:

看来Obj.data 应该是某种列表,而不是requests.Response 对象,对吧? 请求调用返回一个熊猫系列 那么问题可能与 pandas 内存泄漏有关,您最好在帖子和标签中突出显示这一点。相反,您可能应该将 docker 排除在外,除非您只能在通过 docker 运行时重现该问题。 相关:***.com/q/14224068/1025391 这意味着问题绝对是python脚本的一部分,与docker没有任何关系? 【参考方案1】:

正如 moooeeeeep 所建议的,内存使用量的增加与内存泄漏有关,其确切来源仍有待确定。但是,我能够通过在每个循环后通过gc.collect() 手动调用垃圾收集器来解决此问题。

【讨论】:

可能与here 和here 描述的问题相同(熊猫以某种方式泄漏内存)。

以上是关于长时间运行的 Python 程序(使用 Pandas)不断增加内存使用量的主要内容,如果未能解决你的问题,请参考以下文章

Python & Tkinter -> 关于调用冻结程序的长时间运行函数

以与长时间运行的 Python 进程不同的用户身份运行子进程

如何使用 python 烧瓶防止 230 秒 azure 网关超时以进行长时间运行的工作负载

具有长时间运行计算的 Django 应用程序

如何在长时间运行的程序中立即确认 Pub/Sub 消息

如何使用在后端执行的长时间运行的 C/C++ 代码杀死 python 解释器?