gpt4 book ai didi

java - 知道可达性的缓存

转载 作者:行者123 更新时间:2023-11-30 09:33:13 25 4
gpt4 key购买 nike

我想要一个最大保留容量为 N 的缓存。我允许它最多容纳 N 个对象,否则它们将符合 GC 的条件。现在,如果我的应用程序本身当前持有 N+1 个对之前添加到缓存中的对象的强引用,我希望缓存也持有 N+1 个。为什么?因为缓存不会比其他方式更长时间地阻止第 N+1 个对象被收集,而且我愿意用更大的哈希表来换取更多的缓存命中。

换一种说法,我想要一个对象缓存,它保留所有添加到其中的对象,同时它们保持强可达,并且还保留足够的非强可达对象以保持其大小 == N。

例子

我们创建了一个 N=100 的缓存。大小从 0 开始。添加了 150 个对象,大小为 150。这些对象中的 100 个变得非强可及(弱,软,等等)。缓存逐出其中的 50 个并保留 50 个,大小为 100。添加了 49 个更强可达的对象。大小仍然是 100,但现在其中 99 个是强可达的,只有一个是非强可达的。发生的事情是 49 个旧的、非强可达对象被新的 49 个对象替换,因为新对象是强可达的。

动机

我怀疑对于许多用例来说,这实际上是一种直觉。通常,缓存的容量会折衷缓存命中概率以保证最大内存使用。了解其持有的对象的可达性后,缓存可以在不改变其最大内存使用保证的情况下提供更高的缓存命中率。

问题

我担心这在 JVM 上是不可能的。我希望其他人告诉我,但如果你知道一个事实,如果有理由,我也会接受这个答案。

最佳答案

您可以将条目添加到配置为 LRU 或 FIFO 缓存的 LinkedHashMap 中。你也可以有一个 WeakHashMap。如果您将 key 添加到两个映射,LHM 将阻止清理,即使它在 WHM 中也是如此。一旦 LHM 丢弃 key ,它可能在也可能不在 WHM 中。

例如

private final int retainedSize;
private final Map<K,V> lruMap = new LinkedHashMap<K, V>(16, 0.7f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > retainedSize;
}
};
private final Map<K,V> weakMap = new WeakHashMap<K, V>();

public void put(K k, V v) {
lruMap.put(k, v);
weakMap.put(k,v);
}

public V get(K k) {
V v = lruMap.get(k);
return v == null ? weakMap.get(k) : v;
}

这样做的原因之一是 WeakHashMap 会一下子变得更清晰,所以你的命中率会急剧下降。这种方法可确保在您遇到 Full GC 后,您的性能不会在您试图 catch 时下降太多。 ;)

关于java - 知道可达性的缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12326847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com