Ticket #166 (closed defect: fixed)
Memory leak in _speedups.c
| Reported by: | cboos | Owned by: | cmlenz |
|---|---|---|---|
| Priority: | critical | Milestone: | 0.5 |
| Component: | Serialization | Version: | devel |
| Keywords: | memory | Cc: |
Description
While tracking down the memory leak we have in Trac 0.11 [t6303], I had a go at removing the _speedups.so library and that effectively seems to be enough to stabilize the memory usage.
Steps to repeat
Use tracd 0.11 with latest Genshi trunk on a t.e.o clone, then repeatedly query: http://localhost:8910/env/timeline?from=2007-08-20T10%3A15%3A47Z%2B0200&precision=second
- Without _speedups.so, the memory usage stabilizes at 135 Mbytes.
- With _speedups.so, each request adds between 500 and 800K.
In addition, I'm doing a gc.collect() at the end of each request:
-
trac/web/main.py
382 382 finally: 383 383 if env and not run_once: 384 384 env.shutdown(threading._get_ident()) 385 import gc 386 print '----' * 10 387 gc.set_debug(gc.DEBUG_UNCOLLECTABLE) 388 print 'Garbage Collection', gc.collect() 389 print 'Garbage left:', repr(gc.garbage) 390 print 'Objects tracked:', repr(len(gc.get_objects())) 385 391 386 392 def _dispatch_request(req, env, env_error): 387 393 resp = []
The usual output is:
Garbage Collection 0 Garbage left: [] Objects tracked: 47570
(and it stays at 47570)
Reasons
I've not yet located the problem, but so far escape() seems suspicious: the in unicode string doesn't get DECREFed in the inn != 0 case.
Trying the following:
-
genshi/_speedups.c
87 87 88 88 out = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, len); 89 89 if (out == NULL) { 90 Py_DECREF((PyObject *) in); 90 91 return NULL; 91 92 } 92 93 … … 130 131 inp++; 131 132 } 132 133 134 Py_DECREF((PyObject *) in); 135 133 136 args = PyTuple_New(1); 134 137 if (args == NULL) { 135 138 Py_DECREF((PyObject *) out);
which seems better for that particular function, doesn't seem to impact significantly on the leak, so there must be other things.
