MySQLdb - 游标 - 内存泄漏?

时间:2013-10-09 09:09:35

标签: python mysql python-3.x memory-leaks

我在Windows 7上的MySQLdb下使用Python32

Python 3.2.3 (default, Apr 11 2012, 07:12:16) [MSC v.1500 64 bit (AMD64)] on win32
>>> import MySQLdb as My
>>> My.version_info
(1, 2, 3, 'final', 0)

我正在运行服务,一遍又一遍地多次调用它:

cursor = self._connection._conn.cursor()
cursor.execute(sql)
for i in cursor.fetchall(): pass # Operation that is not important
cursor.close()
gc.collect()
return set() # Will be filled with DB data

内存使用情况只是上升和上升,我已经尝试过diagnosing it并以此结束:

83    23.129 MB     0.000 MB           cursor = self._connection._conn.cursor()
84    23.129 MB     0.000 MB           cursor.execute(sql)
85    23.137 MB     0.008 MB           for i in cursor.fetchall(): pass
86    23.137 MB     0.000 MB           cursor.close()
87
88    23.137 MB     0.000 MB           gc.collect()
89
90    23.137 MB     0.000 MB           return set()

__iter__ API似乎都不是更好:

84    23.145 MB     0.000 MB           cursor.execute(sql)
85    23.145 MB     0.000 MB           for i in cursor: pass
86    23.152 MB     0.008 MB           cursor.close()
87
88    23.152 MB     0.000 MB           gc.collect()
89
90    23.152 MB     0.000 MB           return set()

并且都不会使用fetchone()手动循环:

84    23.141 MB     0.000 MB           cursor.execute(sql)
85    23.141 MB     0.000 MB           while True:
86    23.141 MB     0.000 MB               row = cursor.fetchone()
87    23.141 MB     0.000 MB               if not row:
88    23.141 MB     0.000 MB                   break
89    23.148 MB     0.008 MB           cursor.close()
90
91    23.148 MB     0.000 MB           gc.collect()
92
93    23.148 MB     0.000 MB           return set()

那么为什么不将内存清理回23.129MB(为什么它总是使用新的8KB)?光标车有问题吗?我做错了吗?

1 个答案:

答案 0 :(得分:1)

IIRC cursor.fetchall()构建一个内存中的行列表,由于内存分配成本高昂,Python往往会保留已经分配的内存。尝试迭代光标,即for row in cursor: do_something_with(row)