Làm thế nào tôi có thể sử dụng các hàm lru_cache của functools bên trong mà không làm rò rỉ bộ nhớ? Trong ví dụ tối thiểu sau, cá thể foo
sẽ không được giải phóng mặc dù không nằm ngoài phạm vi và không có liên kết giới thiệu nào (ngoài lru_cache).Python functools lru_cache với các phương thức lớp: đối tượng giải phóng
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()
Nhưng foo
và do đó foo.big
(một BigClass
) vẫn còn sống
import gc; gc.collect() # collect garbage
len([obj for obj in gc.get_objects() if isinstance(obj, Foo)]) # is 1
Điều đó có nghĩa rằng trường hợp Foo/BigClass vẫn đang cư trú trong bộ nhớ. Ngay cả khi xóa Foo
(del Foo
) sẽ không phát hành chúng.
Tại sao lru_cache giữ lại đối tượng đó? Không bộ nhớ cache sử dụng một số băm và không phải là đối tượng thực tế?
Cách được khuyến nghị sử dụng lru_caches trong các lớp học là gì?
tôi biết hai cách giải quyết: Use per instance caches hoặc make the cache ignore object (mà có thể dẫn đến kết quả sai, mặc dù)