我遇到了 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,它不会泄漏内存:
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()
我尝试使用 guppy 来追踪泄漏,但它没有帮助。使用 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 位 python 2.7.2(附带 Python(x,y) 2.7.2.3),并使用 .exe 安装程序手动安装了 pyodbc 32 位 3.0.6。哦,我正在使用 MySQL 5.5.17 32 位。
有没有人遇到过这个问题?任何意见都非常感谢。非常感谢!
哦,我忘了告诉我在选择语句之后提交的原因是我正在为 sql 操作编写一个包装器。我无法从语句中判断它是选择还是插入,因此我为每个语句获取并提交,以确保一切都已完成。如果在 select/insert/update/show 之间有一个好的方法来区分,我想我可以避免这个内存泄漏问题。