论文摘要需包含目的、方法、结果和结论四要素,突出创新点,语言简明客观,字数通常不超过300字,是具有独立性和完整性的“迷你论文”。

直接用 weakref 本身无法实现 LRU 语义,因为它不记录访问顺序、不支持容量淘汰、也不感知“最近使用”。但可以基于 WeakValueDictionary(或 WeakKeyDictionary)+ 显式访问追踪 + 定时/按需驱逐,构建一个**内存安全、跨模块共享、带 LRU 行为倾向**的原始数据缓存中心。关键不是替换 LRU,而是用弱引用兜底,再叠加轻量级访问序管理。
核心设计:弱引用兜底 + 访问时间戳标记
缓存中心不长期强持有原始数据对象(如大字节流、解析后的 JSON、嵌入向量张量),而是用 WeakValueDictionary 存储值,同时用普通字典维护每个 key 的最后访问时间戳(time.time())和可选的逻辑权重。当对象被 GC 回收后,时间戳条目可滞后清理,不影响正确性。
- 所有写入:先存入
WeakValueDictionary,同步更新时间戳字典 - 所有读取:先查弱字典是否命中;命中则刷新时间戳;未命中则触发加载并写入
- 驱逐动作:不依赖 GC,而是定期扫描时间戳字典,按时间排序,批量移除最久未用的 key(即使对应 value 还在内存中,也主动从弱字典中 pop)
支持跨模块:用单例 + 异步安全封装
定义一个全局可 import 的缓存实例,内部用 asyncio.Lock 保护写入和驱逐操作,读取可无锁(因 WeakValueDictionary 本身线程安全,且读取不修改结构)。模块间只需:
from cache_center import data_cacheawait data_cache.get("user_123_profile")await data_cache.put("user_123_profile", large_obj)
避免使用模块级全局变量裸露,全部通过方法封装,便于未来替换为 Redis 后端或加日志埋点。
原始数据适配:不序列化、不拷贝、只引用
缓存中心明确只接受“可被弱引用的对象”——即非内置不可变类型(如 str, int, tuple)以外的实例对象。对原始二进制数据(bytes, bytearray)、NumPy 数组、PyTorch 张量等,应包装为轻量容器类(如 class RawDataHolder: __slots__ = ('data',)),再存入弱字典。这样既保留原始内存布局,又避免 bytes 被误当 key 强持有。
- 错误示范:
cache["key"] = b"very_large_blob"→bytes是不可变对象,Python 内部强持有,无法被 weakref 回收 - 正确做法:
cache["key"] = RawDataHolder(b"very_large_blob")→ 实例可被弱引用,GC 触发时自动释放底层 bytes
LRU 倾向强化:结合内存压力动态调优
单纯按时间戳淘汰不够智能。可接入运行时内存指标(如 tracemalloc 快照差值、psutil.Process().memory_info().rss),当瞬态区占用超阈值(如 400MB)时,将驱逐策略从“最近 10 个”升级为“最近 50 个”,或启用语义相似度辅助裁剪(比如同 session 的多个 prompt 缓存,保留最高 attention 权重的那个)。驱逐不阻塞主流程,用 asyncio.create_task() 异步执行。
- 驱逐入口统一:仅暴露
evict_lru(n=10)方法,内部做排序、pop、清空时间戳三步 - 不自动后台轮询:由业务关键路径(如每次推理结束、每 30 秒心跳)显式调用,避免隐式开销
- 失败静默:若某 key 对应 value 已被 GC,
weak_dict.pop(key, None)安全跳过










