[Urwid] Bug: Signal module create backreferences
dom.lobue at gmail.com
Fri Mar 5 03:56:33 EST 2010
On Thu, Mar 4, 2010 at 1:29 PM, Dominic LoBue <dom.lobue at gmail.com> wrote:
> On Thu, Mar 4, 2010 at 12:56 PM, Dominic LoBue <dom.lobue at gmail.com> wrote:
>> On Thu, Mar 4, 2010 at 12:05 PM, Ian Ward <ian at excess.org> wrote:
>>> Dominic LoBue wrote on 2010-03-04 14:55:
>>>> While trying to figure out why my program is eating up so much ram I
>>>> discovered that objects that were supposed to be dead were still
>>>> alive. Much debugging later, I discovered that the problem was caused
>>>> by an object being kept alive by references to it by the
>>>> _urwid_signals attribute its children objects.
>>>> You can probably resolve this problem by using
>>>> weakref.WeakValueDictionary instead of a dict. Although personally I'd
>>>> prefer it if you switch back to having the signal registry in the
>>>> Signals class again (one big dict is smaller than thousands and
>>>> thousands of tiny ones).
>>> Hi Dominic,
>>> I would love some help in this area. I preferred the old method too,
>>> but the way it was being done caused another leak that I couldn't find a
>>> solution to.
>>> If you can make signals work with one dictionary in the Signals class
>>> and not leak objects, please do.
>>> Urwid mailing list
>>> Urwid at lists.excess.org
>> I update the signals class to use your old signals and metasignals
>> classes. You can check it out here for reference:
>> After upping the max_depth argument being passed to objgraph, I ran
>> the example program again and got back a massive png. The PNG is 9
>> megs, so I'll upload the .dot file instead:
>> http://upload.jkvl.com//files/2/objects.dot To generate a png from
>> a .dot file run: dot -Tpng objects.dot -o objects.png (Note:
>> you need graphviz to be installed)
>> I'm still going through the graph, but you may want to take a look at it too.
> Wait, I think I found it:
> <class '__main__.my_object'>: ['something'],
> in Signals._supported
> I changed _supported to a WeakKeyDictionary. This reduced the
> complexity of the graph, but the problem persists...
> Okay, the only thing left now that refers to the parent object
> "my_object" is.... the instance of its own method that is stored in
> the _connections attribute of Signals... Gotta love recursion.
> I made the stored callback a weakref.proxy object, only to get this:
> "ReferenceError: weakly-referenced object no longer exists"
I have a working implementation. By no means is it elegant, but it works.
Basically instead of holding onto the specific method that is to be
called when a signal is recieved, we instead hold onto a tuple of
(ref(parentwithmethod), 'methodname'). When the signal is activated,
we use getattr to get an instance of the method we want and then run
Working examples can be found here:
More information about the Urwid