You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Python中lru_cache装饰类方法的缓存内存占用字节数

追踪lru_cache装饰的类方法的内存占用

你已经可以通过cache_info()获取被lru_cache装饰的类方法的调用统计(命中数、未命中数等),但需要一种类似sys.getsizeof()的方式,提取缓存占用的字节大小。

实现方案

lru_cache的缓存数据实际存储在被装饰方法的__cache__属性(部分Python版本为_cache)中,这是一个字典结构,键为调用方法时的参数元组(包含实例对象和传入参数),值为方法的返回结果。

要计算缓存的总内存占用,需要递归统计字典中所有键值对及其嵌套对象的大小(因为sys.getsizeof()仅返回对象本身的大小,不包含其引用的嵌套对象)。

示例代码

import sys
from functools import lru_cache

def get_total_size(obj, seen=None):
    # 递归计算对象的总内存占用,包含所有嵌套对象
    seen = seen or set()
    obj_id = id(obj)
    if obj_id in seen:
        return 0  # 避免重复计算同一对象
    seen.add(obj_id)
    size = sys.getsizeof(obj)
    
    # 处理常见容器类型
    if isinstance(obj, (list, tuple, set, frozenset)):
        size += sum(get_total_size(item, seen) for item in obj)
    elif isinstance(obj, dict):
        size += sum(get_total_size(k, seen) + get_total_size(v, seen) for k, v in obj.items())
    # 处理自定义对象的属性
    elif hasattr(obj, '__dict__'):
        size += get_total_size(obj.__dict__, seen)
    
    return size

class Exponent:
    def __init__(self, base):
         self.base = base
         
    @lru_cache(maxsize=None)     
    def __call__(self, exponent):
        return self.base ** exponent

# 测试流程
exponent_base_two = Exponent(2)
exponent_base_two(2)
exponent_base_two(3)

# 输出缓存调用统计
print(f"缓存调用统计: {exponent_base_two.__call__.cache_info()}")

# 计算并输出缓存总字节大小
cache = exponent_base_two.__call__.__cache__
total_cache_size = get_total_size(cache)
print(f"缓存总字节大小: {total_cache_size}")

说明

  • get_total_size函数会遍历对象的所有嵌套结构,确保统计到缓存中所有数据的实际内存占用
  • 如果运行时提示__cache__不存在,可尝试替换为_cache(部分Python版本的私有属性命名差异)
  • 统计结果包含缓存字典本身、所有参数元组、返回值对象及其内部引用的所有数据的总字节数

内容的提问来源于stack exchange,提问作者itamar kanter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:47:20