sto sperimentando quello che credo sia una perdita di memoria quando si utilizza l'API MySQLdbPerdita di memoria con ampio set di dati quando si utilizza mysql-python
Line # Mem usage Increment Line Contents
================================================
6 @profile
7 10.102 MB 0.000 MB def main():
8 10.105 MB 0.004 MB connection = MySQLdb.connect(host="localhost", db="mydb",
9 11.285 MB 1.180 MB user="notroot", passwd="Admin123", use_unicode=True)
10 11.285 MB 0.000 MB cursor = connection.cursor(cursorclass=MySQLdb.cursors.SSCursor)
11
12 11.289 MB 0.004 MB cursor.execute("select * from a big table;")
13
14 254.078 MB 242.789 MB results = [result for result in cursor]
15 251.672 MB -2.406 MB del results
16 251.672 MB 0.000 MB return
Anche quando esplorare il cumulo con guppy
/hpy
dimostra che la maggior parte della mia la memoria è occupata da oggetti unicode, interi e oggetti datetime (molto probabilmente per le righe restituite dall'API MySQLdb).
Sto usando Python 2.7.3, mysql-python==1.2.4
su Ubuntu 12.04 e profilato con memory_profiler
.
Potrebbe essere internato come descritto in http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm?
Sono mancante di riferimenti in giro?
EDIT: Ho anche chiuso il cursore e la connessione, ma ho comunque ottenuto risultati simili.
RISOLTO: Facepalm. Stavo facendo una lista di comprensione con naturalmente tenuto tutto in memoria. Quando si consuma l'iteratore correttamente (streaming su un file o qualcosa) ha un uso discreto della memoria.
Line # Mem usage Increment Line Contents
================================================
16 @profile
17 10.055 MB 0.000 MB def main():
18 10.059 MB 0.004 MB connection = MySQLdb.connect(host="localhost", db="mydb",
19 11.242 MB 1.184 MB user="notroot", passwd="Admin123", use_unicode=True)
20 11.242 MB 0.000 MB cursor = connection.cursor(cursorclass=MySQLdb.cursors.SSCursor)
21
22 11.246 MB 0.004 MB cursor.execute("select * from big table")
23 11.246 MB 0.000 MB count = 0
24 30.887 MB 19.641 MB for result in cursor:
25 30.887 MB 0.000 MB count = count + 1
26 30.895 MB 0.008 MB cursor.close()
27 30.898 MB 0.004 MB connection.close()
28 30.898 MB 0.000 MB return
Cosa succede quando si cancella il cursore? Chiudi la connessione? Mi sembra che mi stia nascondendo la cache. Suggerimento: non usare '[foo for foo in bar]' quando un semplice 'list (bar)' farà. –
Inoltre, il sistema operativo non rilascia memoria * immediatamente *. La memoria rimane assegnata a Python nel caso in cui il processo lo richieda nuovamente, viene rimosso dal processo solo se è necessario altrove. Solo perché la memoria deallizzata da python fa ** non ** significa che il sistema operativo immediatamente la recupera. –
Ho dimenticato di chiudere il cursore e la connessione, ma anche dopo averlo fatto, non libererà ancora la memoria –