0
下面的代码泄漏在我的系统存储器:SQLAlchemy的泄漏内存
def test():
for u in users:
session.flush()
some_list = u.some_list
凡users
被定义为
users = session.query(User).yield_per(500000)
和some_list
在用户模型定义为
some_list = relationship("SomeThing", backref="user")
正如你所看到的,跑步session.flush()
不释放使用过的内存。对于这个问题,在循环结束时del some_list
也没有。如果我删除some_list = u.some_list
行,内存泄漏消失。
编辑:根据要求,这里是相关文件的完整代码。但我认为这不会有多大帮助,因为我只能使用功能test()
来重现问题。
from redis import Redis
from pottery import RedisDict
import json
from anime_db import generate_session, User
redis = Redis.from_url('http://localhost:6379')
toshokan = RedisDict(redis=redis, key='toshokan')
session = generate_session(User)
users = session.query(User).yield_per(5000)
users = users[200000:]
def process():
c = 0
for u in users:
session.flush()
if c % 10000 == 0:
print('PROCESSED {} USERS'.format(c))
c += 1
al_db = u.animelist
name = u.name
if len(al_db) == 0 or name in toshokan:
continue
al = []
for a in al_db:
al.append((a.anime_id, a.status, a.num_watched, a.score))
toshokan[name] = json.dumps(al)
del al_db, name, al
def test():
c = 0
for u in users:
session.flush()
if c % 1000 == 0:
print('something')
c += 1
name = u.name
al_db = u.animelist
相关的数据库模型被定义为这样的:
class AnimeEntry(Base):
__tablename__ = 'list_entries_anime'
uid = Column(Integer, Sequence('anime_list_entry_id_seq'), primary_key=True, autoincrement=True)
anime_id = Column(Integer, ForeignKey("anime.uid"), nullable=False)
user_id = Column(Integer, ForeignKey("users.uid"), nullable=False)
status = Column(Integer)
num_watched = Column(Integer)
score = Column(Integer)
added = Column(DateTime(timezone=True), default=func.now())
def __repr__(self):
return "<AnimeEntry(uid='%s', title='%s', user='%s')>" % (self.uid, self.anime_id, self.user_id)
class User(Base):
"""A user entry."""
__tablename__ = 'users'
uid = Column(Integer, Sequence('user_id_seq'), primary_key=True, autoincrement=True)
name = Column(String, unique=True)
joined = Column(DateTime(timezone=True), default=func.now())
animelist = relationship("AnimeEntry", backref="user")
编辑:停止循环不会停止内存使用情况,但运行users = []
事后做。所以这个问题是相关的session.query(User).yield_per(5000)
为什么你认为'session.flush()'会释放内存?你需要'session.expunge_all()'。 – univerio
我被告知别处flush()会工作;它没。对于这个问题,也没有expunge_all()。 –
你怎么看待你有内存泄漏?你的代码的其余部分是做什么的? – univerio