1

私は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

そして、メモリ使用量はどんどん増えていきます。私はすでにそれを診断しようとしましたが、最終的には次のようになりました。

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

IIRC は行cursor.fetchall()のメモリ内リストを作成します。メモリ割り当てはコストがかかるため、Python は既に割り当てられているメモリを保持する傾向があります。代わりに、カーソルを反復処理してみてくださいfor row in cursor: do_something_with(row)

于 2013-10-09T09:18:02.237 に答える