Pandas合并操作内存未释放,多次执行后内存飙升求助
Pandas函数内存无法释放的原因分析
问题场景
正在优化Python脚本的内存占用,其中下述函数的内存消耗极高:
def fn_merge(df1, df2): return pd.\ concat([ df1, df2.\ query( "aderencia_disciplina > 0 and " "interesse == False" ).\ astype({"cod_docente": "int64"}).\ merge( df1.\ astype({"cod_docente": "int64"}).\ drop(["discod", "interesse", "aderencia_disciplina"], axis=1).\ drop_duplicates(), on=["iunicodempresa", "cod_docente"], how="left" ) ])
df1和df2的大小分别为1.7MB和9.9MB,但该函数占用的内存无法释放;执行约20次后,内存占用从约2GB飙升至8GB且始终无法回落。原以为函数执行完毕后,其内部占用的内存会被自动释放,想了解这一现象的原因。
核心原因分析
- 引用未被彻底清除:函数返回的DataFrame如果被外部变量(比如全局列表、循环中的累积变量)持续持有,或者链式调用过程中产生的中间对象(如
query、astype、merge的临时结果)存在隐性引用,Python的引用计数机制就不会回收这些内存。哪怕函数执行完毕,只要有引用存在,对象就会留在内存中。 - Pandas操作的内存开销累积:
astype、merge、concat这类操作都会创建新的DataFrame对象,而部分中间对象可能因Pandas内部的缓存机制、数据块共享引用(比如索引、列的元数据引用)没有被彻底销毁。比如df1.astype({"cod_docente": "int64"})生成新对象后,原df1的部分数据块可能仍被中间对象间接引用,导致无法释放。 - 循环执行的内存泄漏:如果是在循环中重复调用该函数,每次循环产生的临时对象可能因循环变量的引用(比如将每次返回的结果存入容器)无法被垃圾回收。另外,Pandas的部分操作可能返回原始数据的视图而非副本,导致原始df1/df2被意外持有,进一步加剧内存堆积。
- 垃圾回收延迟触发:Python的垃圾回收(GC)不会在对象失去引用后立即执行,尤其是内存占用未达到系统阈值时,会暂时保留未回收对象。如果循环执行频率高,GC来不及处理大量临时对象,就会导致内存持续飙升。
内容的提问来源于stack exchange,提问作者Lfppfs
相关产品推荐
相关产品推荐

