如何分析缓存(番石榴)



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

那么,分析(番石榴)缓存的好方法是什么呢?

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

讨论情况摘要:Aaron Digulla建议使用弱引用,让Java来管理内存。但是在前面的问题中,人们建议"调整,监视,调整"缓存,因为使用弱引用的性能问题。

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

正确的解决方案是调用 stats() 方法。缓存使用的内存量几乎无关紧要,尤其是当您查看内存价格时。从投资回报率的角度来看:如果您花费超过几个小时来尝试内存优化缓存,那么再安装4GB的RAM会更便宜。

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

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

例如,每个类都有一个对类装入器的引用。许多类装入器保留对它们已装入的所有类的引用。如果包括这一点,您的实例的大小将相差甚远。

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

有关 JProfiler 的解决方案,请参阅此问题。

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);

您可以每隔几分钟记录一次,然后分析数据。

我认为有人讨论过提供更好的分析工具来简化 Guava 缓存调整。还提出了"自我调整"缓存的想法。不过,似乎找不到我读到的讨论线程。

最新更新