通过 Java 中对象的深度(与浅度相反)大小限制缓存?
Limit cache by deep (opposite to shallow) size of objects in Java?
我正在缓存图像以便从网络共享 and/or 互联网上更快地下载。目前,这个缓存在内存中。
是否可以通过对象的深度大小来限制缓存(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() method,但不明白这是否是我要找的:文档中没有任何地方指出,计算了权重之和。
简短描述位于 Caches Explained - size based eviction:
Alternately, if different cache entries have different "weights" -- for example, if your cache values have radically different memory footprints -- you may specify a weight function with CacheBuilder.weigher(Weigher)
and a maximum cache weight with CacheBuilder.maximumWeight(long)
. In addition to the same caveats as maximumSize requires, be aware that weights are computed at entry creation time, and are static thereafter.
在你的情况下是这样的:
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
函数。
我正在缓存图像以便从网络共享 and/or 互联网上更快地下载。目前,这个缓存在内存中。
是否可以通过对象的深度大小来限制缓存(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() method,但不明白这是否是我要找的:文档中没有任何地方指出,计算了权重之和。
简短描述位于 Caches Explained - size based eviction:
Alternately, if different cache entries have different "weights" -- for example, if your cache values have radically different memory footprints -- you may specify a weight function with
CacheBuilder.weigher(Weigher)
and a maximum cache weight withCacheBuilder.maximumWeight(long)
. In addition to the same caveats as maximumSize requires, be aware that weights are computed at entry creation time, and are static thereafter.
在你的情况下是这样的:
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
函数。