【问题标题】:Why does Python memory usage goes down after while?为什么 Python 内存使用量会在一段时间后下降?
【发布时间】:2019-12-22 06:05:58
【问题描述】:

具体来说,我最近不得不处理一个大型数据集 (~3 GB),为了了解加载过程的速度(即运行 df = pd.read_csv(file)),我打开了一个任务管理器。

正如我所想,我看到我的 Python 进程的内存使用量不断上升。大约在它达到大约 3 GB 的时候,它已满载。逻辑。

然后,在完成了一些不涉及 Python 的其他任务之后,比如回复电子邮件或在线浏览,我注意到我的任务管理器中的 Python 内存使用率下降了很多,就好像我还没有加载任何数据一样。但我的笔记本内核仍在运行(没有中断)。

奇怪的是,即使在内存使用量降低之后,我的代码仍然可以正常工作:我可以通过运行以下示例来显示来自我的数据帧的信息:

df.loc[100000:101000,['col1','col2','col3']],

立即显示这 1000 行。

或者如果我运行:

df.info(),

这给了我这个:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3228691 entries, 0 to 3228690
Columns: 117 entries, first_column to last_column
dtypes: category(49), float64(51), object(17)
memory usage: 1.8+ GB

这很奇怪,因为当我运行 df.info(memory_usage='deep') 而不仅仅是 df.info() 时,它需要更长的时间,而且我可以在我的任务管理器中看到 Python 进程的内存使用量一直上升到大约 1.5 GB。这是输出:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3228691 entries, 0 to 3228690
Columns: 117 entries, first_column to last_column
dtypes: category(49), float64(51), object(17)
memory usage: 4.9 GB

同样,这很奇怪,因为它的内存使用量达到了 ~1.5 GB,但是输出给出了 4.9 GB 作为 ~3 GB 文件的内存使用量。

我猜 Python 不会将一段时间未使用的内容保存在内存中,但我很好奇这里的规则是什么?这是如何运作的?这是 Pandas 的内存管理过程,还是 Python 的内存管理过程?

【问题讨论】:

  • 如果没有deep 选项,内存使用量是估计值,而不是实际内存量。这是报告虚拟内存,而不是物理 RAM,因此与内存中保存的内容无关。
  • @Barmar 这不是一个估计值,而是没有考虑到 dtype=object 列中对其他 pyhton 对象的引用所占用的内存。我不认为它与虚拟内存有任何关系,它是itemsize * number_of_items的简单等式,但是当item类型为object时,它只是使用机器字(它只考虑指针,而不是对象被参考)
  • 顺便说一句,假设您的 pandas 数据帧需要大约 3 GB,因为您正在读取大约 3 GB 的 csv 文件,这不是一个好的假设。数据在 csv 中表示的方式(作为文本,因此取决于编码,通常每个字符大约 1 个字节)与在主存储器中表示的方式完全不同(作为占用恒定空间的浮点数,作为成熟的 python 对象,它需要 8 字节的指针开销,然后是大量的 python 对象开销,然后是字符串每个字符 1 个字节)
  • @juanpa.arrivillaga 文档特别指出这是一个估计值。我在下面的答案中复制了它。
  • 我的意思是,估计和深度自省都在报告正在使用的虚拟内存量;非特权进程通常无法分辨虚拟内存的哪些部分实际上在 RAM 中。

标签: python pandas dataframe


【解决方案1】:

操作系统的虚拟内存子系统可能会调出一段时间未使用的内存。使用memory_usage='deep' 需要 Pandas 扫描所有这些对象,因此它们会被分页返回,这会导致进程的常驻内存使用量增加。这就是为什么它很慢,它必须从磁盘读取大量信息。

documentation 解释了使用 deep 选项时的区别:

如果没有深入的自省,则基于列 dtype 和行数进行内存估计,假设值消耗相应 dtype 的相同内存量。使用深度内存自省,以计算资源为代价执行真正的内存使用计算。

不管有没有这个选项,它都会报告虚拟内存的数量,无论是估计的还是精确计算的。任务管理器中报告的内存使用量增加只是计算精确数量过程的副作用。

【讨论】:

    猜你喜欢
    • 2014-01-26
    • 2018-11-30
    • 2013-12-21
    • 2020-01-18
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多