了解ehcache以及它如何与Play Framework 2.X一起使用

时间:2014-05-29 04:44:13

标签: playframework playframework-2.0 ehcache playframework-2.2 ehcache-bigmemory

我们在Play 2.2.2应用程序中添加了一些选择Cache.getOrElse()语句来存储一些CPU密集型计算的中间产品。看似简单的胜利!其中有几个是相当复杂的案例类,我们注意到在实现这个之后我们发现了两件事情(a)JVM的内存使用率大幅上升(b)我们得到了一堆警告,如下所示:

 [warn] 20:01:57  net.sf.ehcache.pool.sizeof.SizeOf: The configured limit of 100,000      object references was reached while attempting to calculate the size of the object graph. 
 This can be avoided by adding stop points with @IgnoreSizeOf annotations. Since the CacheManger or Cache <sizeOfPolicy> elements maxDepthExceededBehavior is set to "abort", the sizing operation has stopped and the reported cache size is not accurate. 
 If performance degradation is NOT an issue at the configured limit, raise the limit value using the CacheManager or Cache <sizeOfPolicy> elements maxDepth attribute. 
 For more information, see the Ehcache configuration documentation.

我最初的想法是,因为我们正在存储这些复杂的类,所以Cache正在吸入对象的其他部分,这些部分一旦从缓存中返回就“完全重新构建”对象。因此,我们创建了一些更简单的对象 - 剥离伴随对象,并重新键入不是字符串或Ints的类中的任何字段。但即使是非常简单的字符串映射似乎也会在缓存中存储大量对象(因此我假设使用了大量内存)。

存储redis对象的字符串映射的示例:

val value = Cache.getOrElse[Map[String,String]]("Cache:PicturesForFolios", expiration = 840000){
      client.hgetAll("Bookmarks:Photos")
}

我们正在存储的redis结果图正好有256个键 - &gt;值和jedis库将其作为Map [String,String]返回。那么为什么这会导致&gt;的警告为缓存计算了100000个对象?性能方面,这是一个很大的问题,因为缓存大小的计算需要很长时间,而且我不确定将缓存设置为忽略计算是ehcache被广泛使用时的明智选择!

我没有得到关于ehcache的内容以及它是如何工作的?我是否需要对要放入缓存的任何对象进行自己的序列化,以便将所有内容强制为单个键 - &gt;值???

1 个答案:

答案 0 :(得分:0)

您看到的警告告诉您,您正在调整一个条目(即Key和amp表示的一个或两个对象图表),其中包含超过100k的引用。通常,这意味着您的缓存超出了您的预期,因为这是一个非常大的对象图。在这种情况下,可能与客户返回的内容有关......如果不是这样,我只能想到Play如何使用Ehcache,但我对此一无所知。您需要调查缓存中真正的内容。

显然你不能使用ARC来调整缓存大小(即使用基于计数的大小调整),但是你可能只会隐藏问题,缓存仍会占用大量内存。这会降低推杆的延迟,因为Ehcache不会再尝试调整你的参赛作品。

最后,这与序列化无关,因为大小调整是关于java堆上的对象图。