
guava cache 在未设置 maximumsize 时理论上无硬性条目数上限,但实际受限于 jvm 堆内存;其隐式上限为 integer.max_value(约 21 亿),而真实可用容量通常远低于此值,由对象大小和系统内存共同决定。
当使用 CacheBuilder.newBuilder().build() 创建 Guava Cache(如 Cache
- ✅ 无内置条目数上限:Guava 不会主动限制缓存条目总数;
- ✅ 理论最大容量为 Integer.MAX_VALUE(2,147,483,647):这是由底层 ConcurrentHashMap 及 Guava 内部计数器使用的 int 类型决定的硬边界;
- ❌ 但绝非“无限”:一旦缓存条目持续增长,JVM 堆内存将首先耗尽,触发 OutOfMemoryError。
实际内存消耗示例
假设缓存存储 Long 类型键 + 20 字节 String 值(不含对象头、引用指针等开销):
Cachecache = CacheBuilder.newBuilder().build(); for (long i = 0; i < 10_000_000L; i++) { cache.put(i, "value-" + i); // 每条约占用 ~24 字节(估算) }
1000 万条目 ≈ 占用 240 MB 内存(仅数据部分)。若扩展至 20 亿条目,仅键值数据就超 45 GiB,尚未计入:
- CacheEntry 对象头(12–16 字节/条);
- ConcurrentHashMap 的桶数组、链表/红黑树节点开销;
- Guava 自身的统计元数据(如 accessOrder 链表、写入时间戳等)。
关键注意事项
- ⚠️ 生产环境务必显式配置 maximumSize() 或 maximumWeight():避免不可控内存膨胀;
- ⚠️ 即使启用了 expireAfterWrite() 或 expireAfterAccess(),过期条目不会立即释放内存——需等待下一次读/写操作触发清理,或调用 cleanUp() 主动回收;
- ⚠️ 若依赖弱引用(weakKeys() / weakValues())或软引用(softValues()),虽可缓解 OOM,但会显著增加 GC 压力,且语义复杂,不推荐作为容量控制替代方案。
总结
Guava Cache 的“无 size 限制”本质是将容量控制权完全交予开发者。它提供灵活性,也带来风险。在设计缓存策略时,应始终以 内存可观测性 + 显式容量约束 + 合理过期机制 为黄金三角,而非依赖隐式上限。否则,看似自由的缓存,终将成为压垮服务的内存雪球。









