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))

 

posted @ 2024-11-15 16:36  看一百次夜空里的深蓝  阅读(10)  评论(1编辑  收藏  举报