2013-01-09 103 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