Python Funktools lru_cache mit Klassenmethoden: Objekt freigeben
Wie kann ich den lru_cache von functools in Klassen verwenden, ohne dass Speicherplatz verloren geht? Im folgenden minimalen Beispiel ist dasfoo
Instanz wird nicht freigegeben, obwohl sie den Gültigkeitsbereich verlässt und keinen Referrer hat (außer dem lru_cache).
from functools import lru_cache
class BigClass:
pass
class Foo:
def __init__(self):
self.big = BigClass()
@lru_cache(maxsize=16)
def cached_method(self, x):
return x + 5
def fun():
foo = Foo()
print(foo.cached_method(10))
print(foo.cached_method(10)) # use cache
return 'something'
fun()
Aberfoo
und daherfoo.big
(einBigClass
) leben noch
import gc; gc.collect() # collect garbage
len([obj for obj in gc.get_objects() if isinstance(obj, Foo)]) # is 1
Das bedeutet, dass sich Foo / BigClass-Instanzen noch im Speicher befinden. Sogar das Löschen vonFoo
(delFoo
) wird sie nicht freigeben.
Warum hält lru_cache die Instanz überhaupt fest? Verwendet der Cache keinen Hash und nicht das eigentliche Objekt?
Wie wird die Verwendung von lru_caches in Klassen empfohlen?
ch kenne zwei Problemumgehungen:Use per instance caches oderden Cache das Objekt @ ignorieren lass (was allerdings zu falschen Ergebnissen führen kann)