[New-bugs-announce] [issue44680] Reference cycles from a WeakKeyDictionary value to its key aren’t collected

Anders Kaseorg report at bugs.python.org
Mon Jul 19 17:23:17 EDT 2021


New submission from Anders Kaseorg <andersk at 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 <report at bugs.python.org>
<https://bugs.python.org/issue44680>
_______________________________________


More information about the New-bugs-announce mailing list