Java 如何让Ehcache保留无界缓存的堆大小字节统计信息?
我正在使用Ehcache(版本2.7.1),并希望定期检索统计信息,例如缓存中的元素数量和缓存的大小(以字节为单位)。不过,我遇到的问题是,使用Java 如何让Ehcache保留无界缓存的堆大小字节统计信息?,java,ehcache,Java,Ehcache,我正在使用Ehcache(版本2.7.1),并希望定期检索统计信息,例如缓存中的元素数量和缓存的大小(以字节为单位)。不过,我遇到的问题是,使用net.sf.ehcache.statistics.StatisticsGateway.getLocalHeapSizeInBytes()(通过调用net.sf.ehcache.ehcache.getStatistics())检索StatisticsGateway需要很长时间,有15000个元素,总大小约为536MB。在我本地机器上的一个例子中,获得这个
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即使在未使用maxBytesLocalHeap
缓存设置时也保持堆大小统计信息
<cache name="myCache"
timeToIdleSeconds="1800"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
diskPersistent="false"
maxElementsInMemory="0"
statistics="true"/>
我开始认为我所要求的东西在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
。以下几行创建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));
}
由于池是一个无界池(未指定堆大小),因此创建的PoolAccessor
没有net.sf.ehcache.pool.SizeOfEngine
,但更重要的是类型是net.sf.ehcache.pool.impl.UnboundedPool.unbounddpool.unbounddpoolaccessor
。此类型的add方法不跟踪大小,而为有界池创建的PoolAccessor类型跟踪大小。(请参见net.sf.ehcache.pool.impl.AbstractPoolAccessor.add(对象、对象、对象、布尔值)
)
因此,我很不走运,因为Ehcache有一个我可以使用的设置,但是,如果像我一样,您正在寻找一个无限缓存,那么有一种黑客方法可以实现这个解决方案。下面将在添加内存统计信息时跟踪这些信息,但将允许对缓存进行无限制的添加:
<cache name="myCache"
timeToIdleSeconds="1800"
memoryStoreEvictionPolicy="LRU"
overflowToDisk="false"
overflowToOffHeap="false"
maxBytesLocalHeap="1">
<pinning store="inCache" />
</cache>
@butallmj:向缓存实例添加固定存储将否定MemoryStoreReceiving策略。因此,添加到缓存中的任何项都将始终保留在内存中,即使您是否使用它。相反,我建议使用maxBytesLocalHeap配置为定义的缓存提供边界