JupyterLab中pyarrow.csv.read_csv()内存占用高且无法释放问题排查
JupyterLab中pyarrow加载CSV后内存未释放且持续增长的排查方案
问题概述
在JupyterLab单元格中执行load_csv_by_arrow()函数时,每次运行都会出现内存小幅增长且无法自动释放的情况;但通过!python load_csv_by_arrow.py在JupyterLab中执行独立脚本时无此问题,其他IDE环境下运行也正常。
环境配置
- 操作系统:Windows Server 2016
- 依赖版本:pandas 2.0.0、pyarrow 11.0.0、jupyterlab 3.6.3
- 测试代码:
from pyarrow import csv def load_csv_by_arrow(): table = csv.read_csv(r'./data/xxx.csv') df = table.to_pandas() del df # 在JupyterLab单元格中执行 %memit load_csv_by_arrow()
排查分析与验证步骤
1. 彻底清理函数内的对象引用并强制GC回收
当前代码仅删除了df,但函数内的table对象未显式删除,且Jupyter的交互式环境可能延迟GC回收。修改代码如下:
import gc from pyarrow import csv def load_csv_by_arrow(): table = csv.read_csv(r'./data/xxx.csv') df = table.to_pandas() # 显式删除所有局部变量 del df del table # 强制触发垃圾回收 gc.collect() %memit load_csv_by_arrow()
2. 检查Jupyter命名空间的变量残留
每次执行后,使用%whos魔术命令查看当前内核命名空间中的变量,确认是否有未被清理的pyarrow.Table或pandas.DataFrame对象——这类残留对象会持续占用内存。
3. 排除%memit的统计干扰
%memit本身可能保留执行上下文的引用,换用原生方式监控内存:
import psutil import os def get_memory_mb(): proc = psutil.Process(os.getpid()) return proc.memory_info().rss / (1024 ** 2) # 执行前后对比内存 before = get_memory_mb() load_csv_by_arrow() after = get_memory_mb() print(f"内存变化: {after - before:.2f} MB")
4. 确认pyarrow层面的内存释放
在函数前后打印pyarrow的已分配内存,验证pyarrow对象是否真的释放:
from pyarrow import csv, total_allocated_bytes def load_csv_by_arrow(): print(f"执行前pyarrow内存: {total_allocated_bytes()}") table = csv.read_csv(r'./data/xxx.csv') df = table.to_pandas() del df del table print(f"执行后pyarrow内存: {total_allocated_bytes()}") load_csv_by_arrow()
若执行前后数值一致,说明pyarrow层面无内存泄漏,问题出在Python或Jupyter的内存管理环节。
5. 重启Jupyter内核验证
Jupyter内核长期运行可能积累缓存或无效引用,重启内核后重新测试,排除内核本身的内存积累问题。
可能的根因
- Jupyter交互式环境会追踪单元格执行的变量、调试信息,导致函数内的对象引用未及时被GC回收
%memit魔术命令的实现机制可能保留了函数执行的上下文引用,阻碍内存释放- pandas 2.0.0与pyarrow 11.0.0的组合在交互式环境下,存在引用计数的兼容性问题
内容的提问来源于stack exchange,提问作者Yao
相关产品推荐
相关产品推荐

