1

我正在缓存图像以更快地从网络共享和/或互联网下载。目前,这个缓存在内存中。

是否可以通过对象的深度大小(初步BufferedImageSize)来限制缓存?

缓存初始化如下

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

....

imageCache = CacheBuilder.newBuilder()
         .maximumSize(cacheSize)
         .expireAfterWrite(10, TimeUnit.MINUTES)
         .build(
            new CacheLoader<String, DeferredImage>() {
               public DeferredImage load(String pathname) throws IOException {
                  return new DeferredImage(pathname);

               }
            });

DeferredImage包装器在哪里,BufferedImage以方便在单独的线程中加载。

是否可以编写一些大小检查,它考虑的不是缓存中的条目数,而是它们的字节大小?

更新

我找到了 maximumWeight() 方法,但不明白这是否是我正在寻找的:文档无处说明,计算权重的总和。

4

1 回答 1

1

一个简短的描述是在Caches Explained - size based eviction

或者,如果不同的缓存条目有不同的“权重”——例如,如果你的缓存值有完全不同的内存占用——你可以用 指定权重函数,用 指定CacheBuilder.weigher(Weigher)最大缓存权重CacheBuilder.maximumWeight(long)。除了与 maximumSize 要求相同的注意事项外,请注意权重是在条目创建时计算的,此后是静态的。

在您的情况下,它类似于:

imageCache = CacheBuilder.newBuilder()
     .maximumWeight(maximumCacheSizeInBytes)
     .weigher(new Weigher<String, DeferredImage>() {
        public int weigh(String k, DeferredImage g) {
          return g.size();
        }
     })  
     .build(
        new CacheLoader<String, DeferredImage>() {
           public DeferredImage load(String pathname) throws IOException {
              return new DeferredImage(pathname);

           }
        });

值的类型DeferredImage可能会引起一些麻烦,因为在将值插入缓存时需要知道大小。有一个额外的线程来加载是没有用的,因为插入缓存的线程会阻塞,直到知道大小为止。

替代方案可能值得一提:

Caffeine 的 API 和功能类似于 Guava 缓存,但支持异步加载器。这将允许更好地控制图像加载线程的数量。

EHCache 通过分析值的内存消耗来提供基于大小的驱逐,因此它不需要Weighter函数。

于 2017-03-16T04:19:07.430 回答