【发布时间】:2017-02-20 09:35:03
【问题描述】:
我正在运行一个 python 脚本,可以大致总结(半伪编码)如下:
import pandas as pd
for json_file in json_files:
with open(json_file,'r') as fin:
data = fin.readlines()
data_str = '[' + ','.join(x.strip() for x in data) + ']'
df = pd.read_json(data_str)
df.to_pickle('%s.pickle' % json_file)
del df, data, data_str
该过程以迭代方式创建数据框,并将它们各自保存到一个唯一的文件中。但是,我的内存似乎在这个过程中被耗尽了,好像del df, data, data_str 没有释放内存(本来我没有在代码中包含del 语句,但我希望添加它可以解决问题 - - 它没)。在每次迭代期间,大约相同数量的数据被读入数据帧,大约是我可用内存的 3%;随着进程的迭代,每次迭代都报告了%MEM(来自我的终端中的ps u | grep [p]ython)的 3% 颠簸,最终我的内存被淹没并且进程被杀死。我的问题是我应该如何更改我的代码/方法,以便在每次迭代时释放上一次迭代的内存?
请注意,我通过 Anaconda 运行带有 Python 3.5.2 的 Ubuntu 16.04。
提前感谢您的指导。
【问题讨论】:
-
你是对的,你不需要
delfor循环中的变量,因为每次在循环中重新绑定变量时,旧对象的引用计数都会减少。他们在for完成后闲逛,但如果这是在一个函数中,那么该引用也会消失。我唯一的猜测是clean_json_to_str可能会做一些不好的事情,比如保留对该对象的背景引用。 -
非常感谢您的回答@tdelaney。我已经更新了我的问题,使
clean_json_to_str步骤更加明确,并对我在del调用中投入的所有内容诚实(尽管正如你所提到的,这不应该是问题)。 -
我创建了你的代码版本,我可以测试here,它没有显示出奇怪的内存消耗。您可能会遇到一些颠簸,因为底层堆在前几次迭代中扩展并且有空的可用空间。但这平衡了,对我来说,内存没有增加。
-
为什么要腌制基于 JSON 的数据帧?一般来说,酸洗不是内存效率的,并且对于基于 JSON 的对象来说有点多余。酸洗详情见hbfs.wordpress.com/2013/01/08/python-memory-management-part-ii。我只需将清理后的 JSON 保存在不同的文本文件中,并在需要时使用
json模块读取它。 -
@tdelaney 感谢您的代码并对此进行调查。这对我来说真的很奇怪,而且我的行为方式与你的结果不一致。
标签: python memory-management memory-leaks