Analysing garbage

The garbage function allows you to capture cyclic garbage. Let’s start by creating some cyclic garbage. First we turn off the cyclic garbage collector to prevent the garbage being collected before we have a chance to capure it. We also collect any garbage created by the imports:

>>> import refcycle
>>> import gc
>>> gc.disable()
>>> gc.collect()
0

Now let’s create some reference cycles:

>>> class A(object):
...     pass
...
>>> a = A()
>>> b = A()
>>> a.foo = b
>>> b.foo = a
>>> del a, b, A

After the del statement above, there are no external references either to the two instances of A created, or to the class A. Let’s collect the garbage:

>>> graph = refcycle.garbage()
>>> graph
<refcycle.object_graph.ObjectGraph object of size 10 at 0x10048ed50>
>>> graph.export_image('garbage.svg')

The graph looks something like this:

../_images/garbage.svg

You can see the cycle we created on the right-hand side, along with the references from a and b to the class A, and some cycles belonging to A itself. Now let’s decompose the graph into its strongly connected components, using the strongly_connected_components method:

>>> sccs = graph.strongly_connected_components()
>>> sccs
[<refcycle.object_graph.ObjectGraph object of size 1 at 0x10181e890>,
 <refcycle.object_graph.ObjectGraph object of size 5 at 0x10181e550>,
 <refcycle.object_graph.ObjectGraph object of size 4 at 0x10181e610>]
>>> sccs.sort(key=len)
>>> sccs[-1].export_image('scc1.svg')
>>> sccs[-2].export_image('scc2.svg')
../_images/scc1.svg../_images/scc2.svg

Another useful method is the source_components method: this returns the strongly connected components that aren’t reachable from other strongly connected components. In the context of analysing cyclic garbage, these are the cycles that are keeping the rest of the garbage alive.

>>> graph.source_components()
[<refcycle.object_graph.ObjectGraph object of size 4 at 0x1006a64d0>]