472,127 Members | 1,835 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,127 software developers and data experts.

A memory leak involving builtin/pure-python inheritance.

Hi folks,
Quick Synopsis:

A test script demonstrates a memory leak when I use pythonic extensions
of my builtin types, but if I use the builtin types themselves there is
no memory leak.

If you are interested in how builtin/pure-python inheritance interacts
with the gc, maybe you can help me fix my memory leak.

I'm creating an extension module (see [1]) which implements the LADSPA
host interface (see [2]). A similar project appears to do the same
using pyrex (see [3]), but I have not investigated it yet.

I've discovered a memory leak and I'm fairly certain of the where
the culprit reference cycle is. The problem is I am not sure how
to instruct the gc to handle it, even after reading about supporting
builtin containers (see [4]).
My question:

How do I correctly implement a builtin type and its pythonic extension
type such that reference cycles are detected and collected?

There are three relevant LADSPA types:

A "handle" is an audio processing module which operates on input and
output streams.

A "descriptor" describes the interface to a handle such as the types
in the I/O streams, and their names and descriptions. A handle is the
instantiation of a particular descriptor.

A "plugin" is a container providing zero or more descriptors which can
be dynamically loaded. (Typically a shared object library that the
LADSPA host loads at runtime.)
The python-ladspa package is designed as follows:

There is a low-level builtin extension module, called "_ladspa", and a
high-level interface module, called "ladspa".

For each of the three LADSPA types, there is an extension type in the
"_ladpsa" module, for example: "_ladspa.Descriptor".

For each extension type there is a high-level subtype in the "ladspa"
module. So "ladspa.Handle" inherits from "_ladspa.Handle".
The reference structure of the "_ladspa" module is tree-like with
no cycles. This is because a handle has a single reference to its
descriptor, and a descriptor has a single reference to its plugin.

However, the high-level interface introduces a reference cycle because
this makes the interface more natural, IMO.
I've created a diagram which attempts to represent the inheritance
relationships as well as the reference structure of this wrapper (see
[5]). Let me know if you find it clarifies things or needs
There is a test script, "memleak.py", which tests either module by
repeatedly instantiating and discarding references to handles (see
When configured to use the "_ladspa" module, there appears to be no
memory usage growth, but if using the "ladspa" module, memory grows
linearly with the number of iterations.

If I comment out the "Descriptors" list in the "ladspa.Plugin" class
(which removes the reference cycle) then "memleak.py" runs with no
apparent memory leak.

The leak persists even if I implement traverse and clear methods for
all three builtin types, unless I've done this incorrectly.
Of course one solution is to do away with the reference cycle. After
the _ladspa extension does not have the cycle and is usable. However I
care more about a user-friendly interface (which I believe the
cycle provides) and also I'm just curious.
Thanks for any help,
[1] http://sourceforge.net/projects/python-ladspa/
[2] http://www.ladspa.org/
[3] http://sourceforge.net/projects/dsptools/
[4] http://www.python.org/doc/2.3.5/ext/node24.html

Nov 14 '06 #1
0 1527

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by ranjeet.gupta | last post: by
17 posts views Thread by José Joye | last post: by
20 posts views Thread by jeevankodali | last post: by
6 posts views Thread by Tina | last post: by
3 posts views Thread by Florin | last post: by
22 posts views Thread by Peter | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.