我在gwt-webapp的服务器端使用guava的缓存。 但要正确配置缓存我需要知道一些“遥测”。首先,我需要知道一个缓存条目需要多少内存。 到目前为止,我尝试了jconsole和visualvm。问题是,我不知道在哪里看。我查找了ConcurrencyHashMap及其条目,但找不到正确数量的实例。
那么分析(番石榴)缓存有什么好的,可能很简单的方法呢?
(目前我尚未准备好支付工具以获得近似/平均大小的cach(条目))
讨论状态摘要: Aaron Digulla建议使用弱引用,让Java做管理内存的工作。 但是在previous question中,由于使用弱引用的性能问题,人们建议“调整,监视,调整”缓存。
更新 好吧,我的问题可能是错误的 - 我不想知道缓存或其开销的一些事情。我想知道给定对象的实例有多大 - 配置缓存(在本例中为guava)。我必须回答的第一个问题是:我可以获得内存中的所有实例(100%命中率)或者需要多少内存。如果可能,则不需要缓存配置。如果所有对象都会占用太多内存,我必须考虑配置。我希望有一个工具可以说明对象的平均内存占用量。
答案 0 :(得分:7)
正确的解决方案是调用stats()
方法。缓存使用的内存量几乎无关紧要,尤其是当您查看内存价格时。从投资回报率的角度来看:如果你花费超过几个小时来尝试内存优化你的缓存,安装另外4GB的内存会更便宜。
确定“条目大小”并不容易。根据您放入缓存的值,单个条目的大小可能会有所不同。您可以尝试查找LocalCache.LocalLoadingCache
的实例(如果您在CacheLoader
中使用build()
)或heap dump中使用LocalCache.LocalManualCache
。
这应该给你一个平均大小的实例,但它没有多大帮助:大小不是“递归的”,所以它不考虑引用。包含引用的问题在于停止。
例如,每个类都有一个对类加载器的引用。许多类加载器都会引用它们加载的所有类。如果包含它,那么实例的大小就会偏离。
YourKit非常擅长这种分析,但正如我上面所说,它通常不值得。
答案 1 :(得分:2)
有this question的解决方案,请参见JProfiler。
JProfiler 8将有一个专门的Guava探针。免责声明:我公司开发JProfiler。
答案 2 :(得分:2)
这不是一个真正的外部工具,但您可以使用类似memory-measurer的内容来记录条目的大小。类似的东西:
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);
您可以每隔几分钟记录一次,然后分析数据。
我认为有讨论提供更好的分析工具来简化番石榴缓存调整。还提出了“自我调整”缓存的想法。但是,似乎无法找到我在那里阅读的讨论主题。