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

使用Caffeine缓存存储值后获取为null的问题排查求助

问题分析与解决方案

你的缓存配置和使用中,导致getIfPresent返回null的核心原因是弱引用配置下对象被GC回收,具体细节和解决办法如下:

1. 弱引用配置的影响

你给Caffeine缓存同时配置了weakKeys()和weakValues():

private Cache<Long, SmsData> codeCache = Caffeine.newBuilder()
        .expireAfterWrite(24, TimeUnit.HOURS)
        .weakKeys()
        .weakValues()
        .build();

这两个选项的实际作用:

  • weakKeys():缓存中的键(即你的id)会被包装成弱引用,当JVM触发GC时,如果没有其他强引用指向这个id对象,键会被直接回收,对应的缓存条目也就随之消失。
  • weakValues():缓存中的值(SmsData对象)同理,put到缓存后如果没有其他强引用持有它,GC时会被回收,导致后续get操作返回null。

比如你在方法内创建SmsData对象,方法执行完毕后局部变量的引用消失,此时缓存里的SmsData只有弱引用,一旦触发GC就会被清理。

2. 快速解决办法

方案一:移除弱引用配置(推荐)

如果没有特殊的内存优化需求,直接去掉weakKeys()和weakValues(),改用默认的强引用缓存:

private Cache<Long, SmsData> codeCache = Caffeine.newBuilder()
        .expireAfterWrite(24, TimeUnit.HOURS)
        .build();

这样缓存会持有键和值的强引用,不会被GC随意回收,除非达到设置的过期时间。

方案二:保留弱引用但维持强引用

如果必须使用弱引用,确保在需要缓存的周期内,id和SmsData对象有其他强引用存在:

  • 比如把id存储在类的成员变量、全局集合中,而不是仅作为方法局部变量;
  • SmsData对象在put后,确保其他业务逻辑中还有强引用持有它,直到你不需要缓存它为止。

3. 额外检查点

注意到你创建SmsData的代码:

SmsData data = SopdSmsData();

这里疑似笔误,应该是new SopdSmsData()?如果没有new关键字,代码无法编译通过,如果是你输入时的疏忽,建议先确认对象实例化的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:25:35