MySQLdb - cursor - memory leak?

左心房为你撑大大i 提交于 2021-02-08 09:03:29

问题


I'm using MySQLdb under Python32 on Windows 7:

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)

I'm running service which calls this many times over and over and over again:

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

And memory usage just goes up and up and up, I've already tried diagnosing it and end up with this:

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()

Neither __iter__ API seems to be better:

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()

And neither looping manually with 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()

So why is not memory cleaning back to 23.129MB (why it always uses new 8KB)? Is the cursor buggy? Am I doing something wrong?


回答1:


IIRC cursor.fetchall() builds an in-memory list of rows, and since memory allocation is costly Python tends to retains memory already allocated. Try iterating over your cursor instead, ie for row in cursor: do_something_with(row).



来源:https://stackoverflow.com/questions/19267602/mysqldb-cursor-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!