1

我在 Windows 7MySQLdb下使用: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

并且内存使用量不断上升,我已经尝试过诊断它并最终得到以下结果:

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)呢?光标有问题吗?难道我做错了什么?

4

1 回答 1

2

IIRCcursor.fetchall()构建内存中的行列表,并且由于内存分配成本很高,Python 倾向于保留已分配的内存。尝试迭代您的光标,即for row in cursor: do_something_with(row).

于 2013-10-09T09:18:02.237 回答