如何让Ehcache为无限高速缓存保持堆大小字节数统计?

时间:2013-11-07 16:35:10

标签: java ehcache

我正在使用Ehcache(版本2.7.1),并且希望定期检索统计信息,例如缓存中的元素数量和缓存大小(以字节为单位)。我遇到的问题是,使用net.sf.ehcache.statistics.StatisticsGateway.getLocalHeapSizeInBytes()(通过调用net.sf.ehcache.Ehcache.getStatistics()检索的StatisticsGateway)需要非常长时间使用15000个元素,总大小约为536MB 。在我本地计算机上的一个示例中,获取此统计信息花了超过21秒。

在我经历了这个之后,我想,“如果需要很长时间才能给出堆大小统计数据,那么maxBytesLocalHeap缓存设置在世界上是如何工作的?”我的缓存(如下所示)未设置maxBytesLocalHeap,而是maxElementsInMemory设置。所以,我决定使用maxBytesLocalHeap设置而不是瞧,现在需要大约1毫秒来获取统计数据。

因此,如果缓存不使用maxBytesLocalHeap设置,Ehcache很可能不会保存堆大小的统计信息。相反,它为我为该统计数据进行的每次通话一次又一次地计算每个对象的大小。我想要这些统计数据,我只是不想将它们作为驱逐政策的一部分。所以我接着尝试设置statistics="true",但是我仍然没有更快地获得我的堆大小统计数据。我已经尝试搜索Ehcache文档以找到答案,甚至查看ehcache.xsd我可能遗漏的设置,但我没有发现任何相关内容。

有人知道如何在不使用maxBytesLocalHeap缓存设置的情况下让Ehcache保持堆大小统计信息吗?

<cache name="myCache"
    timeToIdleSeconds="1800"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LRU"
    diskPersistent="false"
    maxElementsInMemory="0"
    statistics="true"/>

2 个答案:

答案 0 :(得分:2)

我开始认为我要求的是Ehcache是​​不可能的(至少是我的版本)

以下是net.sf.ehcache.Cache.class源代码中的池配置:

// on-heap pool configuration
Pool onHeapPool;
if (configuration.getMaxBytesLocalHeap() > 0) {
    PoolEvictor evictor = new FromLargestCachePoolEvictor();
    SizeOfEngine sizeOfEngine = cacheManager.createSizeOfEngine(this);
    onHeapPool = new BoundedPool(configuration.getMaxBytesLocalHeap(), evictor, sizeOfEngine);
} else if (getCacheManager() != null && getCacheManager().getConfiguration().isMaxBytesLocalHeapSet()) {
    onHeapPool = getCacheManager().getOnHeapPool();
} else {
    onHeapPool = new UnboundedPool();
}

稍后,使用net.sf.ehcache.store.MemoryStore从此池创建net.sf.ehcache.store.MemoryStore.MemoryStore(Ehcache, Pool, BackingFactory, SearchManager)。以下行创建net.sf.ehcache.pool.PoolAccessor

if (pool instanceof UnboundedPool) {
    this.poolAccessor = pool.createPoolAccessor(null, null);
} else {
    this.poolAccessor = pool.createPoolAccessor(new Participant(),
        SizeOfPolicyConfiguration.resolveMaxDepth(cache),
        SizeOfPolicyConfiguration.resolveBehavior(cache).equals(SizeOfPolicyConfiguration.MaxDepthExceededBehavior.ABORT));
}

由于池是UnboundedPool(未指定堆大小),因此创建的PoolAccessor没有net.sf.ehcache.pool.SizeOfEngine,但更重要的是类型为net.sf.ehcache.pool.impl.UnboundedPool.UnboundedPoolAccessor。此类型的add方法不跟踪大小,而为有界池创建的PoolAccessor类型也是如此。 (见net.sf.ehcache.pool.impl.AbstractPoolAccessor.add(Object, Object, Object, boolean))。

所以,对于Ehcache有一个我可以使用的设置而言,我运气不好,但是,如果像我一样,你正在寻找一个无限的缓存,那么实现这个解决方案有一种愚蠢的方法。下面将跟踪添加的内存统计信息,但会允许无限制添加到缓存中:

<cache name="myCache"
    timeToIdleSeconds="1800"
    memoryStoreEvictionPolicy="LRU"
    overflowToDisk="false"
    overflowToOffHeap="false"
    maxBytesLocalHeap="1">
    <pinning store="inCache" />
</cache>

答案 1 :(得分:0)

@butallmj:在缓存实例中添加固定存储会取消memoryStoreEvictionPolicy。因此,添加到缓存中的任何项目将始终保留在内存中,即使您使用它也是如此。相反,我建议使用maxBytesLocalHeap配置为定义的缓存提供边界。