You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/memory-leaks.md
+63Lines changed: 63 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,3 +10,66 @@ When a worker has a steadily growing memory usage, here are the steps to find th
10
10
* Start a dedicated worker with ```--trace_memory --greenlets 1``` on the same queue : This will start a worker doing one job at a time with memory profiling enabled. After each job you should see a report of leaked object types.
11
11
* Find the most unique type in the list (usually not 'list' or 'dict') and restart the worker with ```--trace_memory --greenlets 1 --trace_memory_type=XXX --trace_memory_output_dir=memdbg``` (after creating the directory memdbg).
12
12
* There you will find a graph for each task generated by [objgraph](https://mg.pov.lt/objgraph/) which is incredibly helpful to track down the leak.
13
+
14
+
# Using guppy
15
+
16
+
If you want to get an interactive debugging session to deal with high memory usage, you can use [guppy](http://guppy-pe.sourceforge.net/). Here is how:
17
+
18
+
First, initialize a REPL with MRQ configured and guppy loaded:
19
+
20
+
```
21
+
$ pip install guppy
22
+
$ python
23
+
>>> from mrq import config
24
+
>>> from mrq.context import set_current_config, run_task
At this point `h` should contain all the infos you need. You can view an extended debugging session [here](http://smira.ru/wp-content/uploads/2011/08/heapy.html).
39
+
40
+
```
41
+
>>> h
42
+
Partition of a set of 300643 objects. Total size = 41626536 bytes.
43
+
Index Count % Size % Cumulative % Kind (class / dict of class)
44
+
0 130043 43 15682088 38 15682088 38 str
45
+
1 76123 25 6978416 17 22660504 54 tuple
46
+
2 1015 0 2794024 7 25454528 61 dict of module
47
+
3 20181 7 2583168 6 28037696 67 types.CodeType
48
+
4 20610 7 2473200 6 30510896 73 function
49
+
5 2321 1 2095216 5 32606112 78 type
50
+
6 2319 1 2045160 5 34651272 83 dict of type
51
+
7 1277 0 1162808 3 35814080 86 dict (no owner)
52
+
8 2890 1 918352 2 36732432 88 unicode
53
+
9 494 0 440912 1 37173344 89 dict of class
54
+
```
55
+
56
+
So our task added 41.6M of RAM to the current process. Let's see where it comes from, starting by these 15M of strings:
57
+
58
+
```
59
+
>>> h[0].byvia
60
+
Partition of a set of 130043 objects. Total size = 15682088 bytes.
61
+
Index Count % Size % Cumulative % Referred Via:
62
+
0 8208 6 3890208 25 3890208 25 '.func_doc', '[0]'
63
+
1 20065 15 3239664 21 7129872 45 '.co_code'
64
+
2 16673 13 1706224 11 8836096 56 '.co_filename'
65
+
3 2398 2 1606864 10 10442960 67 "['__doc__']"
66
+
4 19810 15 1109640 7 11552600 74 '.co_lnotab'
67
+
5 419 0 308392 2 11860992 76 '.func_doc'
68
+
6 4311 3 285232 2 12146224 77 '[1]'
69
+
7 2788 2 167616 1 12313840 79 '[2]'
70
+
8 2153 2 129136 1 12442976 79 '[3]'
71
+
9 1006 1 109560 1 12552536 80 "['__file__']"
72
+
<21212 more rows. Type e.g. '_.more' to view.>
73
+
```
74
+
75
+
Here, it seems that surprisingly, most of the strings are actually docstrings. This can happen if you work with large Python modules like scipy or boto. One might consider stripping them manually or with Python's optimized mode.
0 commit comments