2013-01-22 53 views
3

我正在製作一個簡單的Web應用程序,它使用flask-sqlalchemy從MySQL數據庫中下拉(很多?目前在兩個表中的64000個字段中) 。我只跑了一個實例,沒有注意到任何問題,直到我用完RAM並且停止了這個事情。我意識到,在Debian Wheezy上使用flask-sqlalchemy進行奇怪的內存使用和泄漏

我可能不得不重新考慮整個事情是如何工作的,因爲我無法繼續添加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() 
+0

而你的代碼是什麼地方? –

+0

因此,您有64000個表條目,每條記錄包含大約80個字節。本身大約爲5MB,但是它如何存儲在Python代碼中很可能會使每條記錄的字節數增加一倍,因此數據本身就是10MB。在構建時,您可能擁有所有數據的不止一個副本,因此,如果您的每個Python代碼實例的大小爲30-40MB,我不會感到驚訝。那麼你到底想要我們怎麼做呢?您可能只想用「限制」一次只抓取部分投注板? –

+0

我希望它在處理後被釋放回操作系統。 –

回答

2

的Python可能不知道何時釋放內存,這樣你就可以幫助它理出頭緒:

import gc 
gc.collect()