我正在使用psycopg2在我的postgres数据库上运行python脚本中的大型查询(我升级到了2.5版)。查询完成后,我关闭游标和连接,甚至运行gc,但该过程仍然消耗大量内存(确切地说是7.3gb)。我是不是错过了一个清理步骤?
import psycopg2
conn = psycopg2.connect("dbname='dbname' user='user' host='host'")
cursor = conn.cursor()
cursor.execute("""large query""")
rows = cursor.fetchall()
del rows
cursor.close()
conn.close()
import gc
gc.collect()发布于 2013-06-20 09:20:53
请查看@joeblog的下一个答案以获得更好的解决方案。
首先,你不应该一开始就需要这么多的RAM。您在这里应该做的是获取结果集的区块。不要做fetchall()。取而代之的是,使用更有效的cursor.fetchmany方法。参见the psycopg2 documentation。
现在,解释为什么它没有释放,以及为什么这不是正式正确使用该术语时的内存泄漏。
大多数进程在释放内存时不会将其释放回操作系统,它们只是让它可用于程序中其他地方的重用。
只有当程序可以压缩分散在内存中的剩余对象时,才能将内存释放给操作系统。这只有在使用间接句柄引用时才有可能,因为否则移动对象将使指向该对象的现有指针无效。间接引用的效率相当低,特别是在现代CPU上,到处追逐指针会对性能造成可怕的影响。
除非程序特别注意,否则通常会发生的情况是,使用brk()分配的每一大块内存都会占用一些仍在使用中的小块内存。
操作系统无法判断程序是否认为该内存仍在使用中,因此它不能只是收回它。由于程序不倾向于访问内存,因此操作系统通常会随着时间的推移将其换出,从而释放物理内存用于其他用途。这是你应该有交换空间的原因之一。
可以编写将内存交还给操作系统的程序,但我不确定您是否可以用Python实现这一点。
另请参阅:
所以:这实际上不是内存泄漏。如果你做的其他事情使用了大量的内存,进程应该不会增长太多,它将重用之前从上次大分配中释放的内存。
https://stackoverflow.com/questions/17199113
复制相似问题