You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame内存重分配未释放旧内存引发OOM错误问题咨询

问题解答

1. 为什么内存消耗不符合float64是float32两倍的对应关系

核心原因有两个:

  • 你初始化生成的narr = np.random.rand(500,1000000)默认就是float64类型,初始DataFrame本身已经占用了约4GB内存,这部分是两种测试场景共有的固定开销,不算在新增列的体积里。
  • 新增的float32列和原有列的dtype不同,不会触发pandas的同类型列合并逻辑。每列float32的总大小极低,500列加起来才1MB左右,所以内存增长几乎可以忽略,看起来和float64场景差异极大,根本不会体现出两倍的体积差。

2. float64场景异常内存波动的原因

你已经排查到的pandas内存块规则是对的:同dtype的列会合并存储,新增列默认是独立块,攒够100个独立块就触发合并。整个合并流程直接导致了你观察到的规律:

  • 首先申请一块足够大的连续内存,用来存储原有所有float64列+新增的100个独立块的全部数据
  • 此时旧的内存块还没有被释放,内存中同时存在新旧两份全量float64数据,所以内存会骤增达到峰值
  • 拷贝完成后,pandas解除对旧内存块的引用,等待Python GC回收旧块占用的内存,内存就会回落
  • 后续新增的float64列又会作为独立块存储,直到攒够100个再次触发合并,所以中间阶段内存保持稳定

剩余疑问解答

是不是内存泄漏?

不是。你观察到的内存没有完全释放是Python内存管理的正常表现:引用解除后,Python不会立刻把空闲内存还给操作系统,而是留在进程的内存池中供后续分配复用,你如果手动调用gc.collect()强制回收,会看到内存占用进一步下降。另外你的测试中内存稳定值是线性增长的,每次增长的幅度刚好对应新增100列的体积,没有出现无限制的暴涨,不存在内存泄漏。

为什么峰值高于稳定值?

合并过程中旧内存块的释放是在新内存块申请+数据拷贝完成之后才进行的,峰值阶段新旧两个全量内存块同时存在于内存中,峰值减稳定值的差值就是旧内存块的大小。

是不是只释放了部分内存?

不是,旧内存块是被完整释放的,只是释放的内存暂时留在进程的内存池中,没有归还给操作系统,从操作系统层面看进程的内存占用不会立刻降到理论值,但这部分内存已经可以被pandas/numpy的后续内存申请复用了。

内容的提问来源于stack exchange,提问作者figs_and_nuts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:15:01