Função python lru_cache com métodos de classe: release object
Como posso usar o lru_cache de functools dentro de classes sem perder memória? No exemplo mínimo a seguir, ofoo
A instância não será liberada apesar de ficar fora do escopo e não ter referenciador (além do 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()
Masfoo
e, portantofoo.big
(umaBigClass
) ainda estão vivos
import gc; gc.collect() # collect garbage
len([obj for obj in gc.get_objects() if isinstance(obj, Foo)]) # is 1
Isso significa que as instâncias Foo / BigClass ainda estão residindo na memória. Mesmo excluindoFoo
(delFoo
) não os liberará.
Por que o lru_cache mantém a instância? O cache não usa algum hash e não o objeto real?
Qual é a maneira recomendada de usar lru_caches dentro das classes?
Conheço duas soluções alternativas:Usar caches por instância oufaça com que o cache ignore o objeto (o que pode levar a resultados errados)