我在Python中打开一个3 GB的文件来读取字符串。然后我将这些数据存储在字典中。我的下一个目标是使用这个字典构建一个图表,所以我正在密切监视内存使用情况。
在我看来,Python将整个3 GB文件加载到内存中,我无法摆脱它。我的代码看起来像这样:
with open(filename) as data:
accounts = dict()
for line in data:
username = line.split()[1]
IP = line.split()[0]
try:
accounts[username].add(IP)
except KeyError:
accounts[username] = set()
accounts[username].add(IP)
print "The accounts will be deleted from memory in 5 seconds"
time.sleep(5)
accounts.clear()
print "The accounts have been deleted from memory"
time.sleep(5)
print "End of script"
最后一行是为了监控内存使用情况。 该脚本在内存中使用超过3 GB的位。清除字典可以释放大约300 MB。当脚本结束时,内存的其余部分将被释放。
我正在使用Ubuntu,并且我使用“系统监视器”和终端中的“免费”命令监视内存使用情况。
我不明白为什么在我清除字典后Python需要这么多内存。文件是否仍存储在内存中?如果是这样,我怎么能摆脱它呢?我的操作系统没有看到释放内存的问题吗?
编辑:我在清除字典后试图强制使用gc.collect(),但无济于事。
EDIT2:我在Ubuntu 12.04.LTS上运行Python 2.7.3
编辑3:我意识到我忘了提到一些非常重要的东西。我真正的问题不在于我的操作系统没有“取回”Python使用的内存。接下来,Python似乎没有重用那个内存(它只是要求操作系统有更多的内存)。答案 0 :(得分:4)
您正在尝试使用哪个版本的python?
我在Python 2.7 / Win7上进行了测试,它按预期工作,内存已经发布。
我在这里生成像你这样的样本数据:
import random
fn = random.randint
with open('ips.txt', 'w') as f:
for i in xrange(9000000):
f.write('{0}.{1}.{2}.{3} username-{4}\n'.format(
fn(0,255),
fn(0,255),
fn(0,255),
fn(0,255),
fn(0, 9000000),
))
然后你的脚本。我用 defaultdict 替换了 dict ,因为抛出异常会使代码变慢:
import time
from collections import defaultdict
def read_file(filename):
with open(filename) as data:
accounts = defaultdict(set)
for line in data:
IP, username = line.split()[:2]
accounts[username].add(IP)
print "The accounts will be deleted from memory in 5 seconds"
time.sleep(5)
accounts.clear()
print "The accounts have been deleted from memory"
time.sleep(5)
print "End of script"
if __name__ == '__main__':
read_file('ips.txt')
如您所见,内存达到1.4G然后被释放,留下36MB:
使用原始脚本我得到了相同的结果,但速度有点慢:
答案 1 :(得分:1)
当Python释放内存以供Python 重用以及将内存释放回操作系统时,存在差异。 Python具有用于某些类型对象的内部池,它将自行重用这些对象,但不会将其返回给操作系统。
答案 2 :(得分:0)
gc module可能很有用,尤其是collect
功能。我自己从未使用它,但从文档中看,它看起来可能有用。在您运行gc.collect()
之前,我会尝试运行accounts.clear()
。