商品详情本地缓存设了 maximumSize(1000),压测二十分钟堆涨到 4G 触发 OOM,每个 value 是 2MB 的详情 JSON,1000 条就是 2G 起步。日志里能对上时间点,这种反而好排。

条数上限不等于内存上限,value 大小差一百倍时,1000 条可能只占几十兆也可能占几个 G。缓存没有按字节计重,淘汰永远轮不到大对象。这一点先确认清楚,后面就不用反复试。

Caffeine.newBuilder()
  .maximumWeight(256L * 1024 * 1024)
  .weigher((k, v) -> jsonSize(v))
  .build();

「本地缓存内存估算」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

别只看报错的最后一行,往上看几行,真正的起因通常在上面。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

处理上按这个顺序:改用 maximumWeight 配 weigher 按序列化后的字节数计重;超过 200KB 的 value 不进本地缓存 放 Redis 或直接查库;把缓存占用打成指标 和堆上限一起看。

结果对不对很好判断,同样压测二十分钟,本地缓存占用稳定在 250MB 左右,堆峰值不到 1G,没有 Full GC。

作者 9823189