在Debian Wheezy上使用flask-sqlalchemy进行奇怪的内存使用和泄漏

时间:2013-01-22 12:42:08

标签: python linux memory-leaks sqlalchemy flask

我正在制作一个简单的网络应用程序,使用flask-sqlalchemy从MySQL数据库中删除(很多当前超过64000个字段在两个表中并且上升)数据。我只运行了一个实例,并且没有注意到任何问题,直到我用尽RAM并且事情停止了。我意识到了

我可能不得不重新考虑整个事情是如何工作的,因为我无法继续添加RAM(它是一个小型虚拟机,所以我从512到768 MB,但仍然是)...但是,乖乖的Python应该释放处理请求后的内存?实际上,当我在Windows机器上运行相同的烧瓶应用程序时,它会吸收RAM(但只有一半!),当它完成时它就会被释放。在运行许多(据称)微型应用程序的Debian机器上并非如此。据我所知,在两台机器上运行的lib版本是相同的。 Debian机器甚至有一个比Windows机器更新的Python版本。他们都连接到同一个数据库。我该怎么办?

from flask import Flask, request, jsonify
from flask.ext.sqlalchemy import SQLAlchemy

import re
from datetime import datetime

app = Flask(__name__)
app.config.from_pyfile('settings.cfg')
db = SQLAlchemy(app)

class Reports(db.Model):
    __tablename__ = 'reports'

    id          = db.Column(db.Integer, primary_key=True)
    ip          = db.Column(db.Integer)
    date        = db.Column(db.DateTime)
    sid         = db.Column(db.Integer)
    version     = db.Column(db.Integer)
    itemname    = db.Column(db.String(25))
    group       = db.Column(db.Integer)
    pclass      = db.Column(db.String(15))
    ltime       = db.Column(db.Integer)
    rlen        = db.Column(db.Integer)
    total       = db.Column(db.Integer)

    def __init__(self, pd):
        self.date = datetime.utcnow()
        self.sid = pd["sid"]
        self.version = pd["version"]
        self.itemname = pd["itemname"]
        self.group = pd["group"]
        self.pclass = pd["pclass"]
        self.ltime = pd["ltime"]
        self.rlen = pd["rlen"]
        self.total = pd["total"]


class Perfdata(db.Model):
    __tablename__ = 'perfdata'

    reportid    = db.Column(db.Integer, db.ForeignKey('reports.id'), primary_key=True)
    l70 = db.Column(db.Integer)
    l65 = db.Column(db.Integer)
    l60 = db.Column(db.Integer)
    l55 = db.Column(db.Integer)
    l50 = db.Column(db.Integer)
    l45 = db.Column(db.Integer)
    l40 = db.Column(db.Integer)
    l35 = db.Column(db.Integer)
    l30 = db.Column(db.Integer)

    def __init__(self, reportid, pd):
        self.reportid = reportid
        self.l70 = pd["l70"]
        self.l65 = pd["l65"]
        self.l60 = pd["l60"]
        self.l55 = pd["l55"]
        self.l50 = pd["l50"]
        self.l45 = pd["l45"]
        self.l40 = pd["l40"]
        self.l35 = pd["l35"]
        self.l30 = pd["l30"]

    def buildlist(self):
        plist = []

        plist.append(self.l70)
        plist.append(self.l65)
        plist.append(self.l60)
        plist.append(self.l55)
        plist.append(self.l50)
        plist.append(self.l45)
        plist.append(self.l40)
        plist.append(self.l35)
        plist.append(self.l30)

        return plist


@app.route('/ps', methods=['GET'])
def perfget():

    response = []

    for report, perf in db.session.query(Reports, Perfdata).all():

        response.append("")

        response.append("%s %s %s %s %s %s %s %s" % (report.version,
                                                     report.sid,
                                                     report.itemname,
                                                     report.group,
                                                     report.pclass,
                                                     report.ltime,
                                                     report.rlen,
                                                     report.total))

        response.append("%s %s %s %s %s %s %s %s %s" % (perf.l70,
                                                     perf.l65,
                                                     perf.l60,
                                                     perf.l55,
                                                     perf.l50,
                                                     perf.l45,
                                                     perf.l40,
                                                     perf.l35,
                                                     perf.l30))

    return '<br>\n'.join(response)


if __name__ == '__main__':
    app.run()

1 个答案:

答案 0 :(得分:2)

Python可能不知道何时释放内存,因此您可以帮助它解决问题:

import gc
gc.collect()