2013-01-09 65 views
10

我有一个运行在uwsgi下的似乎泄漏内存的django webserver。挡板非对象python内存泄漏

特别是,进程的RSS缓慢增长,直到最终我必须重新启动它。

我知道其他类似的问题,但到目前为止所发现的所有解决方案/结论似乎并不适用(我可以找到)。

到目前为止,我已经使用meliaeHeapypymplerobjgraph检查蟒蛇堆,他们都报同样的事情:使用约一段时间的记忆(预期)用很少的方差40MB正常看着堆(如需要的话)。

这很不幸与整个流程RSS完全不一致,它将愉快地增长到400MB +,而没有反映在python堆大小中。

一些示例输出来说明我的点 -

Pympler输出进行比较蟒堆/对象存储器VS过程RSS:

Memory snapshot: 
             types | # objects | total size 
============================================= | =========== | ============ 
             dict |  20868 |  19852512 
              str |  118598 |  11735239 
             unicode |  19038 |  10200248 
             tuple |  58718 |  5032528 
             type |  1903 |  1720312 
             code |  13225 |  1587000 
             list |  11393 |  1289704 
          datetime.datetime |  6953 |  333744 
              int |  12615 |  302760 
    <class 'django.utils.safestring.SafeUnicode |   18 |  258844 
             weakref |  2908 |  255904 
    <class 'django.db.models.base.ModelState |  3172 |  203008 
        builtin_function_or_method |  2612 |  188064 
         function (__wrapper__) |  1469 |  176280 
             cell |  2997 |  167832 
          getset_descriptor |  2106 |  151632 
          wrapper_descriptor |  1831 |  146480 
              set |   226 |  143056 
             StgDict |   217 |  138328 
--------------------------- 
Total object memory: 56189 kB 
Total process usage: 
- Peak virtual memory size: 549016 kB 
- Virtual memory size: 549012 kB 
- Locked memory size: 0 kB 
- Peak resident set size: 258876 kB 
- Resident set size: 258868 kB 
- Size of data segment: 243124 kB 
- Size of stack segment: 324 kB 
- Size of code segment: 396 kB 
- Shared library code size: 57576 kB 
- Page table entries size: 1028 kB 
--------------------------- 

Heapy输出表示类似的事情

Memory snapshot: 
Partition of a set of 289509 objects. Total size = 44189136 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 128384 44 12557528 28 12557528 28 str 
    1 61545 21 5238528 12 17796056 40 tuple 
    2 5947 2 3455896 8 21251952 48 unicode 
    3 3618 1 3033264 7 24285216 55 dict (no owner) 
    4 990 0 2570448 6 26855664 61 dict of module 
    5 2165 1 1951496 4 28807160 65 type 
    6 16067 6 1928040 4 30735200 70 function 
    7 2163 1 1764168 4 32499368 74 dict of type 
    8 14290 5 1714800 4 34214168 77 types.CodeType 
    9 10294 4 1542960 3 35757128 81 list 
<1046 more rows. Type e.g. '_.more' to view.> 
--------------------------- 
Total process usage: 
- Peak virtual memory size: 503132 kB 
- Virtual memory size: 503128 kB 
- Locked memory size: 0 kB 
- Peak resident set size: 208580 kB 
- Resident set size: 208576 kB 
- Size of data segment: 192668 kB 
- Size of stack segment: 324 kB 
- Size of code segment: 396 kB 
- Shared library code size: 57740 kB 
- Page table entries size: 940 kB 
--------------------------- 

请注意,在这两种情况下,报告的堆大小为40-50MB,w当时的流程RSS是200MB +。

我也使用objgraph的get_leaking_objects()尝试查看C扩展是否做错坏计数,但非gc'able对象的数量不会显着增长。

有没有人有任何见识到如何去调试呢?在这一点上,我假设两件事情之一是这样的:

  • 我有一个C的扩展内存泄露内部
  • uwsgi本身正在泄漏内存(虽然我能找到的这个就没有其他证据净)

值得一提的是,我没有成功复制这种在任何开发环境(尽管它可能我只是没有足够的流量在他们)。

我们确实使用了一堆具有C扩展(simplejson,hiredis等)的模块,所以它们确实可以成为它们的原因。

寻找方法来追踪这一点。

+0

你有settings.py DEBUG = False,对吧? – monkut

+0

是的,但很好的问题:) – fenn

+0

我想知道你是否最终解决了这个问题?我们遇到类似的问题,这些问题在切换到uwsgi后才遇到。 – Geekfish

回答

2

你正在使用什么版本的Python?在Python 2.4中,内存没有被Python内存分配器返回到操作系统。

还是在更新的版本中,您可以看到一个问题,它或者与Python的内存分配器有关,它会保留已释放简单类型的列表,或者如果您在Linux上运行,glibc的malloc实现如何从操作系统分配内存。看看http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htmhttp://pushingtheweb.com/2010/06/python-and-tcmalloc/

+0

Python 2.6(Ubuntu 10.04本机)在我们的情况。我会研究malloc问题,但我还没有碰到过这个问题。 – fenn