为什么Python不释放内存(在mod_wsgi + Django下)

时间:2013-10-22 12:15:57

标签: python django memory-leaks mod-wsgi

我有Apache + mod_wsgi + Django个应用。 mod_wsgi以守护进程模式运行。

我有一个视图从DB获取重要的查询集,另外通过计算查询集的结果来分配数组,然后返回此数组。我没有使用线程本地存储,全局变量或任何类似的东西。

问题是我的应用程序相对于我为mod_wsgi设置的数字线程来占用内存

我通过在mod_wsgi中设置不同数量的线程然后通过curl检查wsgi进程可以在多大程度上进行内存爬升来进行小型实验。

它是这样的:

1 thread  - 256Mb
2 threads - 400Mb
3 threads - 535Mb
4 threads - 650Mb

因此每个线程在最高内存使用量上添加大约120-140Mb。

我似乎永远不会释放为第一个请求分配的初始内存。在单线程场景中,当第二个请求(到同一视图)到达时,它会被重用。我可以离开。

但是当我使用多个线程时,那么当一个从未运行过此请求的线程处理请求时,该线程会在本地“保存”另一个140mb。

  • 如何解决这个问题?
  • 可能Django会在TSL中保存一些数据。如果那样的话 如果是这样,我怎么能禁用它?
  • 或者,作为一种解决方法,是吗? 可以将请求执行绑定到mod_wsgi
  • 中的某个线程

感谢。

PS。 DEBUG

中的settings.py设置为False

1 个答案:

答案 0 :(得分:9)

在这种情况下,您应该做的是对Web应用程序进行垂直分区,使其跨多个mod_wsgi守护程序进程组运行。这样,您就可以将mod_wsgi守护程序进程的配置定制为您委派给每个进程的URL子集的要求。由于Django应用程序的管理界面URL通常具有较高的瞬态内存使用要求,但却不经常使用,因此建议您这样做:

WSGIScriptAlias / /my/path/site/wsgi.py
WSGIApplicationGroup %{GLOBAL}

WSGIDaemonProcess main processes=3 threads=5
WSGIProcessGroup main

WSGIDaemonProcess admin threads=2 inactivity-timeout=60
<Location /admin>
WSGIProcessGroup admin
</Location>

这样做是为了创建两个守护进程组。默认情况下,URL将在主守护进程组中处理,其中进程是持久的。

但是,对于管理界面的URL,它们将被定向到管理守护程序进程组,该进程组可以使用具有减少的线程数的单个进程设置,加上不活动超时,以便该进程将自动重新启动如果60秒后未使用管理界面,则回收任何过多的瞬态内存使用。

这意味着如果从上次开始回收流程,那么向管理界面提交请求可能会稍微减慢,因为所有内容都必须再次加载,但由于它是管理界面而不是公共URL,这通常是可以接受的。