New submission from Anders Kaseorg <ande...@mit.edu>: Because WeakKeyDictionary unconditionally maintains strong references to its values, the garbage collector fails to collect a reference cycle from a WeakKeyDictionary value to its key. For example, the following program unexpectedly leaks memory:
from weakref import WeakKeyDictionary class C: pass d = WeakKeyDictionary() while True: c = C() d[c] = [c] I would expect a WeakKeyDictionary value to be marked live _if_ its key is marked live, not unconditionally. This could be implemented with garbage collector support for ephemerons (https://www.researchgate.net/publication/221320677_Ephemerons_A_New_Finalization_Mechanism). To motivate this issue, a typical use of WeakKeyDictionary is as a hygienic replacement for patching extra properties into third-party objects: # before: obj._extra_state = ExtraState(obj) # after: extra_states = WeakKeyDictionary() extra_states[o] = ExtraState(obj) However, such a conversion will introduce this memory leak if ExtraState(obj) has any transitive references to obj. This leak does not occur in JavaScript: class C {} const d = new WeakMap(); while (true) { const c = new C(); d[c] = [c]; } ---------- components: Library (Lib) messages: 397841 nosy: andersk priority: normal severity: normal status: open title: Reference cycles from a WeakKeyDictionary value to its key aren’t collected type: resource usage versions: Python 3.9 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue44680> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com