2013-06-14 9 views
9

を使用しているとき、私は私がメモリリークの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 

をMySQLdbはAPIを使用する際にメモリリークであると信じて何を経験しています。また、それは私のそのほとんどを示していますメモリはユニコードオブジェクト、ints、およびdatetimeオブジェクトによって占有されています(MySQLdb APIによって返される行は非常にありそうです)。

私はUbuntu 12.04でPython 2.7.3,mysql-python==1.2.4を使用し、memory_profilerでプロファイルしています。

http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htmに記載されているように、

何か参考文献がありません。

EDIT:また、カーソルと接続を閉じても、同様の結果が得られました。

解決済み: Facepalm。私は自然にメモリ内のすべてを保持してリストの理解をしていました。イテレータを適切に消費するとき(ファイルや何かにストリーミングするとき)には、まともなメモリ使用量があります。

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 
+0

カーソルを削除するとどうなりますか?接続を閉じますか?これは私にキャッシングするように聞こえる。ヒント:単純な 'list(bar)'が行うときに '[foo for bar in]'を使わないでください。 –

+2

また、OSはメモリ*をすぐに解放しません。メモリがPythonに割り当てられたままになっている場合は、プロセスがもう一度それを必要とするため、必要な場合にのみプロセスから削除されます。単にPythonがメモリを解放したから**はOSが即座にそれを再利用することを意味しません**。 –

+0

カーソルと接続を閉じるのを忘れましたが、それでも実行してもメモリは解放されません。 –

答えて

1

OPによって解決されます。彼の元のコードには行が含まれていた

このリストの理解度は、必要に応じてサーバからストリーミングするのではなく、結果全体をメモリに保存しました。 OPは簡単にそれを置き換えた

for result in cursor: 
    ... 

と彼のメモリ使用量が正常に戻って見た。