Django Python垃圾收集的困境

2024-10-01 07:40:54 发布

您现在位置:Python中文网/ 问答频道 /正文

经过两天的调试,我终于掌握了自己的时间:Python垃圾回收器。
我的应用程序在内存中保存了很多对象。而且效果很好。
GC会进行常规回合(我没有使用默认阈值(700、10、10))。
偶尔,在一个重要的交易过程中,第二代扫描会启动并检查我的约150万个第2代对象。
这需要2秒钟! 名义交易所需时间少于0.1秒。在

我的问题是我该怎么做?
我可以关闭第2代扫描(通过设置一个非常高的阈值-这是正确的方法吗?)而且总司令很听话。
我什么时候打开?
我们使用Django实现了一个web服务,每个用户请求大约需要0.1秒。
最理想的情况是,我将在用户API请求之间运行GC gen 2循环。但我该怎么做呢?
我的视图以return HttpResponse()结束,在之后,我希望运行第2代GC扫描。
我该怎么做?这种方法有意义吗?在

我可以标记不需要垃圾收集的对象,这样GC就不会每第二代周期测试它们吗?
当Django服务器相对空闲时,如何配置GC来运行完全扫描?在

多平台(Windows/Linux)上的Python2.6.6。在


Tags: 对象django方法内存用户应用程序时间阈值
3条回答

我认为一个选择是完全禁用垃圾收集,然后在请求结束时手动收集,如下所示:How does the Garbage Collection mechanism work?

我想您可以禁用settings.py文件中的GC。在

如果您想对每个请求运行GarbageCollection,我建议您开发一些中间件,在process response方法中执行:

import gc
class GCMiddleware(object):
    def process_response(self, request, response):
        gc.collect()
        return response

另一种选择可能是完全禁用GC,并配置mod\uwsgi(或您正在使用的任何东西)以更频繁地终止和重新启动进程。在

我们为古尼康做了这样的事。根据您使用的wsgi服务器,您需要在响应之后而不是之前找到正确的钩子。Django有一个request_finished信号,但该信号仍然是预响应。在

对于gunicorn,在配置中需要定义两个方法,如下所示:

def pre_request(worker, req):
    # disable gc until end of request
    gc.disable()


def post_request(worker, req, environ, resp):
    # enable gc after a request
    gc.enable()

这里的post_request在http响应被传递之后运行,因此是垃圾收集的好时机。在

相关问题 更多 >