我们的咖啡因缓存存在问题。我们将其配置为大小为60,TTL为300秒,如下所示:
Cache<String, String> cache = Caffeine.newBuilder()
.expireAfterWrite(300, TimeUnit.SECONDS)
.maximumSize(60)
.removalListener((String key, String value, RemovalCause cause) -> {
cacheListenerHandler(key, value, cause);
})
.build();
现在,removationListener的定义如下:
private void cacheListenerHandler(String key, String value, RemovalCause cause) {
if (RemovalCause.EXPIRED.equals(cause)) {
if (value != null) {
LOG.info("We got TTL expiry of key {} and value {}",
key, value);
} else {
LOG.warn("Value is null for TTL expiry! key: {}", key);
}
}
if (RemovalCause.SIZE.equals(cause)) {
if (value != null) {
LOG.info("We got SIZE expiry of key {} and value {}",
key, value);
//some logic
} else {
LOG.warn("Value is null for SIZE expiry! key: {}", key);
}
}
}
话虽如此,我们这样插入缓存:
public void registerValue(String key, String value) {
cache.put(key, value);
LOG.info("Key {} was added with value {}. Current estimated size of {} keys in cache",
key, value, cache.estimatedSize());
}
问题在于有时我们会收到诸如以下的日志:
键'key1'已添加值'value1'。当前估计的缓存中250个键的大小
我们不断看到(侦听器方法的)逐出日志:
我们获得了密钥“ key1”和值“ value1”的SIZE到期时间
再过一秒钟,日志:
键'key2'已添加值'value2'。当前估计的缓存中251个键的大小
现在,我知道'estimatedSize'的细微差别-它包含将要收回的键,但是问题是我们遇到了Java内存堆问题,这意味着实际删除发生得太晚了,无法使用。
有解决方案吗?也许我们需要改用番石榴了吗?