使用pandas.read_pickle填充字典时Python进程被终止的问题
AWS Ubuntu环境下Pandas加载Pickle文件到字典时进程异常终止问题
问题现象
在AWS运行的Ubuntu 18.04.5镜像中,执行代码通过pandas.read_pickle()加载7个DataFrame并将其存入字典时,Python进程会在完成所有文件加载前被强制终止。但存在以下例外情况:
- 仅读取Pickle文件但不赋值给字典元素时,循环可正常完成
- 将相同DataFrame转存为Feather格式,用
pandas.read_feather()加载并存入字典时,循环也能正常完成 - 相同代码、相同Pickle文件在MacOS 12.6.2环境下(同版本Python/Pandas,均为conda安装)无此问题
环境信息
- 受影响环境:AWS Ubuntu 18.04.5,conda安装的Python 3.8.8 + Pandas 1.2.4;曾测试Python 3.8.15 + Pandas 1.5.2,问题复现
- 正常环境:MacOS 12.6.2,conda安装的同版本Python/Pandas
可能原因分析
- 内存资源耗尽(OOM Killer触发):AWS实例内存有限,多个Pickle格式DataFrame加载到字典后内存占用激增,Ubuntu的OOM(内存不足)机制会直接终止占用内存过高的进程。Pickle反序列化后的内存占用通常高于Feather这类列式存储格式,且MacOS的内存管理机制相对宽松,不会轻易终止进程。
- Pickle跨平台反序列化异常:虽然Pickle设计为跨平台,但如果DataFrame包含特定扩展类型(如自定义对象、特定numpy dtype),Ubuntu环境下的反序列化过程可能存在内存泄漏或底层库兼容性问题,导致进程崩溃。
- Conda包底层依赖差异:即使Python和Pandas版本号一致,Ubuntu和MacOS的conda包编译依赖的底层库(如numpy、libgfortran等)可能存在版本或编译选项差异,引发隐性兼容性问题。
解决方案建议
- 监控内存使用情况:执行代码前用
htop或top实时监控内存占用,确认是否触发OOM。如果是内存不足导致:- 升级AWS实例的内存配置
- 调整代码逻辑,分批加载DataFrame,处理完成后及时释放内存(如
del df+gc.collect()),避免一次性存入字典
- 优化Pickle加载参数:尝试指定更高版本的Pickle协议,如
pd.read_pickle(f, protocol=4),新版本协议在内存效率和跨平台兼容性上更优 - 替换序列化格式:长期来看,优先使用Feather、Parquet这类专为DataFrame设计的列式存储格式,它们在跨平台兼容性、加载速度和内存效率上均优于Pickle
- 对齐Conda环境依赖:分别在Ubuntu和MacOS环境执行
conda list导出包列表,对比底层依赖库的版本差异,尝试将Ubuntu环境的依赖包版本调整为与MacOS一致 - 排查进程崩溃细节:在Ubuntu下执行
ulimit -c unlimited启用核心转储,进程终止后生成core文件,用gdb python core.<PID>分析崩溃栈,定位具体异常点
内容的提问来源于stack exchange,提问作者lebedov
相关产品推荐
相关产品推荐

