Python cache 内存泄漏问题
@functools.cache 函数装饰器在一些特殊情况的时候会影响变量引用计数器的计数,从而导致内存泄漏。比如:@functools.cache和@@functools.property一起使用的时候,或者更复杂的嵌套引用
1 from functools import wraps 2 3 4 class CacheManager: 5 def __init__(self): 6 self._cache = {} 7 8 def get_cache_obj(self, key): 9 """获取缓存对象""" 10 return self._cache.get(key) 11 12 def add_cache_obj(self, key, obj): 13 """添加缓存对象""" 14 self._cache[key] = obj 15 return obj 16 17 def __del__(self): 18 """清除所有缓存对象""" 19 # print(f"CacheManager del") 20 for k, v in self._cache.items(): 21 # print(f"CacheManager del:{k=}") 22 del v 23 self._cache.clear() 24 del self._cache 25 26 @classmethod 27 def cache_result(cls, func): 28 """ 29 装饰器:缓存结果,支持参数作为缓存的唯一键。 30 """ 31 32 @wraps(func) 33 def wrapper(instance, *args, **kwargs): 34 # 根据函数名和参数构建唯一缓存键 35 key = f"{func.__name__}:{args}:{kwargs}" 36 37 # 检查是否已缓存 38 cache_obj = instance.cache_manager.get_cache_obj(key) 39 if cache_obj is not None: 40 return cache_obj 41 42 # 缓存中没有对象,执行函数并缓存结果 43 result = func(instance, *args, **kwargs) 44 instance.cache_manager.add_cache_obj(key, result) 45 return result 46 47 return wrapper
测试demo
1 from base.utils.tools import CacheManager 2 3 4 class MyClass: 5 def __init__(self): 6 self.cache_manager = CacheManager() 7 8 def __del__(self): 9 print("MyClass.__del__") 10 11 @property 12 @CacheManager.cache_result 13 def oms_user(self): 14 # 该代码只在缓存不存在时执行 15 return [1, 2, 3] 16 17 18 def test_cache(): 19 m = MyClass() 20 print(id(m.oms_user)) 21 print(id(m.oms_user))