我正在使用Ehcache(版本2.7.1)并且想要定期检索统计信息,例如缓存中的元素数量和缓存大小(以字节为单位).我遇到的问题是使用net.sf.ehcache.statistics.StatisticsGateway.getLocalHeapSizeInBytes()(通过调用检索的StatisticsGateway net.sf.ehcache.Ehcache.getStatistics())需要很长时间才能使用15000个元素,总大小约为536MB.在我的本地计算机上的一个示例中,获得此统计信息花费了超过21秒.
在我经历了这个之后,我想," maxBytesLocalHeap如果需要很长时间才能给出堆大小统计数据,那么缓存设置在世界上是如何工作的?" 我的缓存,如下所示,没有设置maxBytesLocalHeap,而是maxElementsInMemory设置.所以,我决定使用这个maxBytesLocalHeap设置而不是瞧,现在需要大约1ms才能得到我的统计数据.
因此,如果缓存不使用该maxBytesLocalHeap设置,Ehcache似乎很可能不会保存堆大小的统计信息.相反,它为我为该统计数据进行的每次通话一次又一次地计算每个对象的大小.我想要这些统计数据,我只是不想将它们作为驱逐政策的一部分.所以我接着尝试设置statistics="true",但是我仍然没有更快地获得我的堆大小统计数据.我已经尝试搜索Ehcache文档以找到答案,甚至通过ehcache.xsd查看我可能遗漏的设置,但我没有发现任何相关内容.
有没有人知道如何在maxBytesLocalHeap不使用缓存设置的情况下让Ehcache保持堆大小统计?
<cache name="myCache"
timeToIdleSeconds="1800"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
diskPersistent="false"
maxElementsInMemory="0"
statistics="true"/>
Run Code Online (Sandbox Code Playgroud)
我开始认为 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();
}
Run Code Online (Sandbox Code Playgroud)
稍后net.sf.ehcache.store.MemoryStore,使用 从此池中创建a 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));
}
Run Code Online (Sandbox Code Playgroud)
由于池是 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>
Run Code Online (Sandbox Code Playgroud)