3

pyodbcでメモリリークの問題が発生しました。追跡するのに多くの時間がかかりました。最後に、メモリリークが発生するコードを取得しました。

import pyodbc
conn = pyodbc.connect(myconnstr)
cur = conn.cursor()
for i in range(1000000):
    print i
    cur.execute('select * from test.aa;')
    cur.fetchall()
    cur.commit()

このコードを実行すると、約5mb/秒でメモリをゆっくりと消費します。ただし、以下のように最後の行を削除しても、メモリがリークすることはありません。カーソルと接続を繰り返し閉じても効果はありません。メモリリークが発生した場合、カーソルを閉じると接続によってメモリが元に戻りません。

import pyodbc
conn = pyodbc.connect(myconnstr)
cur = conn.cursor()
for i in range(1000000):
    print i
    cur.execute('select * from test.aa;')
    cur.fetchall()

ただし、selectをinsertステートメントに置き換えても、メモリはリークしません。

import pyodbc
conn = pyodbc.connect(myconnstr)
cur = conn.cursor()
for i in range(1000000):
    print i
    cur.execute('insert into test.aa values(1);')
    cur.commit()

グッピーを使って漏れを追跡しようとしましたが、役に立ちません。hpy()。heap()を使用すると、次の結果が得られます。

Partition of a set of 286322 objects. Total size = 22433376 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0 115601  40  8825424  39   8825424  39 str
     1  69891  24  3030424  14  11855848  53 tuple
     2   1921   1  1352588   6  13208436  59 dict (no owner)
     3   1074   0  1349016   6  14557452  65 dict of PyQt4.QtCore.pyqtWrapperType
     4    477   0  1189980   5  15747432  70 dict of module
     5  12326   4   887472   4  16634904  74 types.CodeType
     6  12178   4   730680   3  17365584  77 function
     7   1162   0   565496   3  17931080  80 dict of type
     8   1162   0   523384   2  18454464  82 type
     9   1074   0   502632   2  18957096  85 PyQt4.QtCore.pyqtWrapperType
<1140 more rows. Type e.g. '_.more' to view.>

22MBのメモリしか使用されていないとのことですが、実際にはPythonプロセスは現時点で約500MBを使用しています。

32ビットのpython2.7.2(Python(x、y)2.7.2.3に付属)を使用しており、.exeインストーラーを使用してpyodbc32ビット3.0.6を手動でインストールしています。ああ、私はMySQL5.5.1732ビットを使用しています。

誰かが以前にこの問題に遭遇したことがありますか?コメントをいただければ幸いです。どうもありがとう!

ああ、selectステートメントの後にコミットする理由は、SQL操作のラッパーを書いているからだと言うのを忘れていました。ステートメントからそれが選択であるか挿入であるかを判断できないため、すべてが完了したことを確認するために、すべてのステートメントをフェッチしてコミットします。選択/挿入/更新/表示を区別する良い方法があれば、このメモリリークの問題を回避できると思います。

4

1 に答える 1

0

解決策は見つかりませんでしたが、回避策は見つかりました。一部のマシンでのみ問題が発生していました。あなたのコード スニペットの助けを借りて、これらがどれであるかを絞り込むことができ、MySQL ODBC コネクタのバージョン 5.2 を使用している場所で発生したすべてのものと、使用している場所で漏れていないものに気付きました。 5.1. これは、Windows と Linux の両方で発生しました。

リークのあるマシンで 5.1 にダウングレードすると、問題が解決 (または少なくとも回避) されたようです。

于 2013-01-21T17:12:51.217 に答える