Flask + uwsgi + nginx: 何时释放内存?

3 投票
1 回答
1848 浏览
提问于 2025-04-18 17:48

我正在用Flask构建一个API。

假设我有这样一个Flask路由:

@app.route('/api/tasks', methods=['GET'])
@auth.login_required
def tasks():
    tasks = g.user.tasks
    task_list = []
    for t in tasks:
        d = {}
        d['name'] = t.name
        d['id'] = t.id
        task_list.append(d)
    return jsonify({'tasks':task_list})

那么“tasks”和“task_list”这两个变量占用的内存会在响应返回后立刻释放吗?

在我的情况中,似乎uwsgi进程并没有在每次请求后释放它们所使用的内存,至少看起来不是在每次返回后就释放。

这些任务是通过Flask-SQLAlchemy扩展从MySQL数据库中获取的。

谢谢!

编辑:这是我的uwsgi配置文件(/etc/flask-uwsgi/flask-uwsgi.ini):

[uwsgi]
master = true
die-on-term = true
processes = 1
threads = 2
logger = file:/var/log/flask-uwsgi/flask-uwsgi.log

我这样调用它:

uwsgi  --socket 127.0.0.1:8080 -w wsgi:app --ini /etc/flask-uwsgi/flask-uwsgi.ini --stats /tmp/statsock --memory-report

1 个回答

3

这里提到的 taskstask_list 都是局部变量,当这个视图函数返回时,它们就会失去绑定。

它们里面的内容是否会被释放,取决于是否还有其他地方在引用这些数据。Python 对象会在它们的引用计数降到 0 时被清除,所以如果还有其他地方在使用这些对象,它们就不会被清除。

举个例子,task_list 这个列表对象没有其他引用,所以会立即被清除。这个列表里包含了新的 dict 对象(在循环中用 d 引用),这些字典也没有其他引用,所以也会被清除。这些字典的键是字符串;这些字符串是可以重复使用的(在这种情况下,它们是被存储的,每个字符串对象只有一份拷贝),所以不需要被清除。

剩下的就是 t.namet.id 的值,还有 g.user.tasks 的引用。如果 g.user.task 是一个列表对象,那么 g.user.task 就是对那个对象的引用,它不会被清除。t.namet.id 的值也可能在其他地方被引用,所以它们会继续存在。不过,这通常是件好事。

撰写回答