【发布时间】:2013-10-31 07:24:50
【问题描述】:
我有Apache + mod_wsgi + Django 应用程序。 mod_wsgi 以守护程序模式运行。
我有一个视图,它从数据库中获取重要的查询集,并通过计算查询集的结果另外分配数组,然后返回这个数组。我没有使用线程本地存储、全局变量或类似的东西。
问题是我的应用消耗内存相对于我为 mod_wsgi 设置的线程数。
我做了一个小实验,通过在 mod_wsgi 中设置不同数量的线程,然后通过 curl 检查 wsgi 进程可以内存爬升多远来访问我的视图。
是这样的:
1 个线程 - 256Mb 2 个线程 - 400Mb 3 个线程 - 535Mb 4 线程 - 650Mb所以每个线程在最高内存使用量上增加了大约 120-140Mb。
我似乎永远不会释放为第一个请求分配的初始内存。在单线程场景中,当第二个请求(对同一视图)到达时,它会被重用。这样我就可以离开了。
但是当我使用多个线程时,当请求由以前从未运行过此请求的线程处理时,该线程会在本地某处“保存”另外 140mb。
- 如何解决这个问题?
- 可能 Django 在 TSL 中保存了一些数据。如果那是 这种情况下,我该如何禁用它?
- 或者,作为一种解决方法,是
可以将请求执行绑定到
mod_wsgi中的某个线程吗?
谢谢。
PS。 DEBUG 在settings.py 中设置为 False
【问题讨论】:
-
您是否 a) 仅在数据集到达时创建数组,b) 在完成后将其删除,以便垃圾收集器可以访问它?
-
a) - 是的; b) - 我没有明确地删除它。我将其转换为 JSON 并返回 JSON 字符串。
-
不删除它还在使用中!
-
这不是真的。只要事物没有以某种方式显式缓存,它们就应该能够在使用它们的最后一个作用域退出时立即清理。唯一可能不是这种情况的情况是数据在对象之间创建了引用计数循环,在这种情况下,需要等待垃圾收集器启动并尽可能打破循环。
-
OP 没有明确说明的是在多线程情况下,请求是序列化的还是同时运行的。如果序列化,由于它管理线程的方式,最多 mod_wsgi 守护程序模式应该只激活两个线程而不是四个。无论如何,这很可能是由于应用程序级别的某种缓存,因为 mod_wsgi 本身并没有做任何事情来保留数据。
标签: python django memory-leaks mod-wsgi