Java 如何配置缓存(番石榴)

Java 如何配置缓存(番石榴),java,profiling,guava,Java,Profiling,Guava,我正在使用我的gwt webapp服务器端的guava缓存。 但要正确配置缓存,我需要知道一些“遥测”。首先,我需要知道一个缓存条目占用多少内存。 到目前为止,我尝试了jconsole和visualvm。问题是,我不知道去哪里看。我查找了ConcurrencyHashMap及其条目,但找不到正确数量的实例 那么,什么是一种很好而且可能很简单的分析(番石榴)缓存的方法呢 (目前,我还不准备为一个工具付费,以获得cach大小的近似值/平均值(条目)) 讨论情况总结: Aaron Digulla建议使

我正在使用我的gwt webapp服务器端的guava缓存。 但要正确配置缓存,我需要知道一些“遥测”。首先,我需要知道一个缓存条目占用多少内存。 到目前为止,我尝试了jconsole和visualvm。问题是,我不知道去哪里看。我查找了ConcurrencyHashMap及其条目,但找不到正确数量的实例

那么,什么是一种很好而且可能很简单的分析(番石榴)缓存的方法呢

(目前,我还不准备为一个工具付费,以获得cach大小的近似值/平均值(条目))

讨论情况总结: Aaron Digulla建议使用弱引用,让Java来管理内存。 但是在一个例子中,人们建议“调优、监视、调优”缓存,因为在使用弱引用时存在性能问题

更新
好吧,我的问题可能是误导性的——我不想知道有关缓存或其开销的一些事情。我想知道给定对象的实例有多大——配置缓存(在本例中为guava)。我必须回答的第一个问题是:我是否可以获得内存中的所有实例(100%命中率)或者这需要多少内存。如果可能,则不需要缓存配置。若所有对象占用太多内存,我必须考虑配置。我希望有一个工具可以说明对象的平均内存占用。

正确的解决方案是调用
stats()
方法。缓存使用的内存量几乎是无关紧要的,特别是当您查看内存价格时。从投资回报率的角度来看:如果你花几个小时以上的时间来优化你的缓存,再安装一个4GB的RAM会更便宜

此外,确定“条目大小”也不容易。根据您在缓存中输入的值,单个条目的大小可能会有所不同。您可以尝试查找
LocalCache.LocalLoadingCache
(如果在
build()
中使用
CacheLoader
)的实例,或在中使用
LocalCache.LocalManualCache

这应该会给出实例大小的平均值,但不会有多大帮助:大小不是“递归的”,所以它不考虑引用。包含引用的问题是在哪里停止

例如,每个类都有一个对类加载器的引用。许多类加载器保留对它们加载的所有类的引用。如果包括了这一点,那么实例的大小将大为不同

非常擅长这种分析,但正如我上面所说的,它通常不值得这样做。

请参阅,以获得一个解决方案


JProfiler 8将配备专用番石榴探头。免责声明:我的公司开发了JProfiler。

它不是一个真正的外部工具,但您可以使用类似于日志的工具来记录条目的大小。比如:

Cache cache = ...
// copy the entries to avoid measuring the footprint of the "EntrySet view"
List<Map.Entry<K, V>> entries = ImmutableList.copyOf(cache.asMap().entrySet());
long memory = MemoryMeasurer.measureBytes(entries);
logger.trace("Size of %s entries : %s bytes", entries.size(), memory);
缓存=。。。
//复制条目以避免测量“EntrySet视图”的示意图
List entries=ImmutableList.copyOf(cache.asMap().entrySet());
长内存=MemoryMeasurer.measureBytes(条目);
logger.trace(“%s项的大小:%s字节”,entries.Size(),内存);
您可以每隔几分钟记录一次,然后分析数据


我认为有人讨论过提供更好的评测工具来简化Guava缓存调优。还提出了“自调整”缓存的想法。但是,似乎找不到我读到的讨论线程。

我只需要配置缓存的大小:给定内存量可以容纳多少个条目。动态配置cach似乎不是一个好主意:人们建议“正确的做法是仔细选择一个最大大小,它本质上限制了缓存将消耗的内存总量”和“我们强调经典的“调优,监视,调优”-我被困在“监视”“-部分再次阅读我答案的第一句话。对不起,我不明白:你的哪一部分有助于获得有关记忆的信息?最后,我想在服务器配置中提供一个设置(“可用内存”),我的代码应该设置一个使用这个内存的缓存大小。这是java,不是C++。要么使用弱引用来防止缓存增长过快,要么在逐出率太高的情况下向服务器添加更多RAM。(上面提到的关于“弱”引用的所有内容实际上都是关于软引用的。)我阅读了问题B。我只想提一句,我不想为了得到缓存项大小的近似值/平均值而付钱。Ingo,我在哪里可以了解更多关于“专用番石榴探测器”的信息?谢谢!实际上,这将是一个Guava cache probe,但它只是计划到目前为止,还没有实现。@Ingo,请注意,
cache
的实现几乎肯定会随着时间的推移而改变——如果您正在计划任何特定于实现的工具,请与我们保持联系。另一个解决方案是指向您的分析器(jconsole、jvisualvm、yourkit、jprofiler…)在缓存项列表中,使用
ImmutableList.copyOf(cache.asMap().entrySet())
获得。这使您可以独立于缓存的数据结构查看每个项的内存占用。