4

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

那么,什么是分析(番石榴)缓存的好方法和可能简单的方法?

(目前我还没有准备好支付工具来获得缓存(条目)大小的近似值/平均值)

讨论状态总结:Aaron Digulla 建议使用弱引用并让 Java 完成管理内存的工作。但是在之前的问题中,由于使用弱引用的性能问题,人们建议“调整、监控、调整”缓存。

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

4

3 回答 3

7

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

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

这应该为您提供实例大小的平均值,但它不会有太大帮助:大小不是“递归的”,因此它不考虑引用。包含引用的问题是在哪里停止。

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

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

于 2012-04-16T07:57:28.790 回答
2

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

JProfiler 8 将有一个专用的 Guava 探针。免责声明:我公司开发 JProfiler。

于 2012-04-16T08:46:45.853 回答
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);

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

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

于 2012-04-16T11:33:05.990 回答