python - 为什么 Python 内存使用量会在一段时间后下降?
问题描述
具体来说,我最近不得不处理一个大型数据集(~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 的内存管理过程?
解决方案
操作系统的虚拟内存子系统可能会调出一段时间未使用的内存。使用memory_usage='deep'
需要 Pandas 扫描所有这些对象,因此它们会被重新分页,这会导致进程的常驻内存使用量增加。这就是为什么这很慢,它必须从磁盘读取大量信息。
文档解释了使用该deep
选项时的区别:
如果没有深入的自省,则基于列 dtype 和行数进行内存估计,假设值消耗相应 dtype 的相同内存量。使用深度内存自省,以计算资源为代价执行实际内存使用计算。
无论有没有这个选项,它都会报告虚拟内存的数量,无论是估计的还是精确计算的。任务管理器中报告的内存使用量增加仅仅是计算精确数量过程的副作用。
推荐阅读
- angular - Angular11 Web 应用程序被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Headers 不允许访问控制允许来源
- android - 这行“_contacts?.length ?? 0”在颤振/飞镖中是什么意思
- java - 执行器保护时找不到 HttpSecurity bean
- c++ - 在 Visual Studio 中创建 dll 项目时附加依赖库的说明
- javascript - 将鼠标放在图像上时更改为另一个图像的图像
- python - 沿特定方向的元素乘积的numpy总和
- kubernetes-helm - 如果图表值发生变化,Helm 升级会重启 Pod
- forms - 如何在引用备用表单的访问表单中创建“转到下一个”记录按钮
- bootstrap-4 - 如何使引导表列排序图标更明显?
- python - Jupyter Dashboard - 以奇怪的格式显示数据