使用psutil.Process.memory_info的内存使用情况与Pandas.memory_usage不同

11
我正在对一个使用 Pandas 处理一些 CSV 文件的程序进行性能分析。我使用 psutil的Process.memory_info 报告虚拟内存大小 (vms) 和常驻集大小 (rss) 的值。我还使用 Pandas 的 DataFrame.memory_usage(df.memory_usage().sum()) 报告我在内存中的 dataframes 的大小。
在报告的 vmsdf.memory_usage 值之间存在冲突,其中 Pandas 仅为 dataframe 报告了更多的内存,而 Process.memory_info 调用仅为整个(单线程)进程报告了相对较少的内存。
例如:
  • rss:334671872 B
  • vms:663515136 B
  • df.memory_usage().sum():670244208 B
Process.memory_info 调用是在 memory_usage 调用之后立即进行的。我原来期望的结果是 df.memory_usage < vms,但这并不成立。我猜测我可能误解了 vms 值的含义?

1
你是在Jupyter还是像PyCharm这样的IDE中运行它?如果你是在Jupyter中运行它,请尝试使用IDE并发布是否获得相同的结果。ipkernel似乎没有按预期方式管理内存。 - Trenton McKinney
这些值来自由nosetests生成的日志。在ipython中探索时,我看到了类似的行为。 - musingsole
1
我在循环中运行了一些测试,创建数据,从数据创建一个数据帧并测量内存,但我无法重现 df.memory_usage().sum() > vms 的问题。 - Trenton McKinney
如果您在测试程序中创建数据,那可能会导致与我的设置不同。该数据存在于一个CSV文件中,使用read_csv读入,所有列都是字符串。 - musingsole
1
我更新了我的流程。我创建了一个文件,反复读取它,并测量了内存。df.memory_usage().sum() = 670,000,128vms=815,214,592保持不变。我有32GB的RAM和5GB的虚拟内存。你的读数似乎意味着df的大小大于正在使用的虚拟内存(页面文件)的数量。顺便说一下,VM只是硬盘上分配的空间。 - Trenton McKinney
1个回答

4

这是与您问题相关的参考资料: 使用RSS或VMS跟踪内存。关于RSSVMS之间的关系有些令人困惑,您可以在这里详细了解这些概念。您还应该知道如何在此处此处计算总内存使用量。

**总结并补充我的观点**:


RSS:

驻留集大小用于显示分配给进程在RAM中的内存量。它不包括被交换出的内存

它涉及共享库中的内存,包括所有堆栈和堆内存。

VMS:

虚拟内存大小包括进程可以访问的所有内存。这包括;

被交换出的内存,已分配但未使用的内存以及来自共享库的内存。

例子:

假设一个Process-X有一个500-K的二进制文件,链接到2500-K的共享库,分配了200-K的堆栈/堆内存,其中100-K实际上在内存中(其余被交换或未使用),并且它实际上只加载了1000-K的共享库和400-K的自己的二进制文件,则:

RSS: 400K + 1000K + 100K = 1500K
VMS: 500K + 2500K + 200K = 3200K

在这个例子中,由于一部分内存是共享的,因此许多进程可能会使用它,所以如果将所有 RSS 值相加,很容易就会得到比系统拥有的更多的空间。
正如您可以看到的,当您简单运行这个命令时;
import os
import psutil
process = psutil.Process(os.getpid())
print("vms: ", process.memory_info().vms)
print("rss:", process.memory_info().rss)

输出:

vms: 7217152

rss: 13975552

只需添加import pandas as pd,您就可以看到差异。

import os
import psutil
import pandas as pd
process = psutil.Process(os.getpid())
print("vms: ", process.memory_info().vms)
print("rss:", process.memory_info().rss)

以下是输出结果:

vms: 276295680

rss: 54116352

因此,分配的内存可能直到程序实际使用后才会出现在RSS中。如果您的程序一开始就分配了大量内存,然后随着时间的推移逐渐使用它,则:

  • 您可以看到RSS上升并且VMS保持不变。

现在无论您选择 df.memory_usage().sum() 还是 Process.memory_info ,我相信RSS包括来自动态链接库的内存。因此,它们的RSS之和将比实际使用的内存更多。


我很感激RSS和VMS值的背景,但这并不能解释为什么Pandas的df.memory_usage().sum()会报告比VMS更高的值,因为VMS应该是可访问内存的全部范围。 - musingsole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接