Как я могу использовать lru_cache functools внутри классов без утечки памяти? В следующем минимальном примере экземпляр foo
не будет выпущен, хотя он выходит за пределы области видимости и не имеет реферера (кроме 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()
Но foo
и, следовательно, foo.big
(a BigClass
) все еще живы
import gc; gc.collect() # collect garbage
len([obj for obj in gc.get_objects() if isinstance(obj, Foo)]) # is 1
Это означает, что экземпляры Foo / BigClass все еще находятся в памяти. Даже удаление Foo
(del Foo
) не освободит их.
Почему lru_cache вообще удерживает экземпляр? Разве в кеше не используется какой-то хеш, а не сам объект?
Как рекомендуется использовать lru_caches внутри классов?
Я знаю два обходных пути: использовать кеши для каждого экземпляра или заставить кеш игнорировать объект (хотя это может привести к неверным результатам)