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

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

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

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

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

  

我开始认为我要求的是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.MemoryStore(Ehcache, Pool, BackingFactory, SearchManager)从此池创建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(未指定堆大小),因此创建的net.sf.ehcache.pool.SizeOfEngine没有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有一个我可以使用的设置而言,我运气不好,但是,如果像我一样,你正在寻找一个无限的缓存,那么实现这个解决方案有一种愚蠢的方法。 以下内容将跟踪添加的内存统计信息,但将允许对缓存进行无限制的添加:

    

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