Java Guava缓存大小方法不返回缓存中的实际条目数

Java Guava缓存大小方法不返回缓存中的实际条目数,java,caching,google-guava-cache,Java,Caching,Google Guava Cache,我在应用程序中使用guava缓存来提高性能。我已经使用中的putAllAPI在缓存中插入了850个条目。我配置的最大缓存大小为20K个条目。我正在使用测试类TestCacheSize测试缓存大小: public class MetadataCacheKey{ // implementation } public class Metadata{ // implementation } public class MetadataCacheLoader extends CacheL

我在应用程序中使用guava缓存来提高性能。我已经使用中的putAllAPI在缓存中插入了850个条目。我配置的最大缓存大小为20K个条目。我正在使用测试类TestCacheSize测试缓存大小:

public class MetadataCacheKey{
    // implementation
}

public class Metadata{
    // implementation
}

public class MetadataCacheLoader extends CacheLoader<MetadataCacheKey, Optional<Metadata>> {
    /**
     * Guava cache does not support null values in cache. So null response from metadata source is wrapped in Optional
     * and loaded in cache. This reduces look ups for keys which are not present in source.
     */
    @Override
    public Optional<Metadata> load(@NonNull MetadataCacheKey key) throws Exception {
        return Optional.fromNullable(loadMetadataFromSource(key));
    }
    private Metadata loadMetadataFromSource(MetadataCacheKey key) {
        // implementation
    }
}

public class TestCacheSize {
    public static void main(String[] args) {
        LoadingCache<MetadataCacheKey, Optional<Metadata>> metadataCache = CacheBuilder.from(
                "expireAfterWrite=4h,maximumSize=20000").build(new MetadataCacheLoader());
        metadataCache.putAll(getAllMetadataFromDb());
        System.out.println(metadataCache.size());         // output is 9467 (amusing)
        System.out.println(metadataCache.asMap().size()); // output is 850  (as expected)
    }
    // assume always returns map with size equal to 850
    private static Map<MetadataCacheKey, Optional<Metadata>>  getAllMetadataFromDb(){
        return new HashMap<MetadataCacheKey, Optional<Metadata>>();
    }
}
公共类MetadataCacheKey{
//实施
}
公共类元数据{
//实施
}
公共类MetadataCacheLoader扩展了CacheLoader{
/**
*Guava缓存不支持缓存中的空值。因此,来自元数据源的空响应包装为可选
*并加载到缓存中。这减少了对源中不存在的密钥的查找。
*/
@凌驾
公共可选加载(@NonNull MetadataCacheKey)引发异常{
返回可选的.fromNullable(loadMetadataFromSource(key));
}
私有元数据loadMetadataFromSource(MetadataCacheKey){
//实施
}
}
公共类TestCacheSize{
公共静态void main(字符串[]args){
LoadingCache metadataCache=CacheBuilder.from(
“expireAfterWrite=4h,maximumSize=20000”).build(新MetadataCacheLoader());
putAll(getAllMetadataFromDb());
System.out.println(metadataCache.size());//输出为9467(有趣)
System.out.println(metadataCache.asMap().size());//输出为850(如预期)
}
//假设始终返回大小等于850的映射
私有静态映射getAllMetadataFromDb(){
返回新的HashMap();
}
}
缓存大小的起始值:

size返回缓存中条目数的近似值


有人能解释一下850到9467之间的近似值吗?

可能重复的问题我没有从上面的问题中得到答案,因为它谈到缓存中的无效条目是主要原因。在我的例子中,我第一次插入了所有条目,并且在850中插入了最大数量的条目。因此,无效条目的最大数量不能超过850。那么,这个数字为什么会接近850的11倍呢?@chammu你能给我们展示更多的代码,说明你是如何创建和填充缓存的吗?添加了代码。我还没有添加一些实现细节,比如从数据库获取数据。已经有一段时间了。最新版本的番石榴有这个问题吗@我没有从上面的问题中得到答案,因为它谈到缓存中的无效条目是主要原因。在我的例子中,我第一次插入了所有条目,并且在850中插入了最大数量的条目。因此,无效条目的最大数量不能超过850。那么,这个数字为什么会接近850的11倍呢?@chammu你能给我们展示更多的代码,说明你是如何创建和填充缓存的吗?添加了代码。我还没有添加一些实现细节,比如从数据库获取数据。已经有一段时间了。最新版本的番石榴有这个问题吗@查姆