【问题标题】:grails-cache-ehcache plugin in Grails app for caching using @Cacheable annotationsGrails 应用程序中的 grails-cache-ehcache 插件,用于使用 @Cacheable 注释进行缓存
【发布时间】:2014-06-01 16:29:48
【问题描述】:

我的情况是我有 Grails 2.1.2 应用程序,并希望引入使用 cache plugincache-ehcache plugin 作为实现的方法级缓存。

我的缓存是这样配置在内存中的:

  grails.cache.config = {
    cache {
        name 'homePageCache'
        enabled true
        eternal false
        pinning {
            store 'localMemory'
    }
  }

我有一个像这样的方法,它只接受 int 参数,所以密钥生成不是问题:

  @Cacheable('homePageCache')
  TubeVideoPagingArray findHomePageOfVideos(int pageSize) {

我的问题是调用此方法时出现java.lang.OutOfMemoryError: Java heap space 异常。原因是 ehcache 使用一个名为 ObjectGraphWalker 的类计算将要放入缓存的对象的大小,该类遍历对象图并对大小求和。

我已经为 ehcache 设置了一个调试级别的日志记录,并看到了大量与这些类似的行:

2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'bigDecimalMultiplier' of class java.text.DecimalFormat
2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'digitList' of class java.text.DecimalFormat
2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'positivePrefixFieldPositions' of class java.text.DecimalFormat
2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'positiveSuffixFieldPositions' of class java.text.DecimalFormat
2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'negativePrefixFieldPositions' of class java.text.DecimalFormat
2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'negativeSuffixFieldPositions' of class java.text.DecimalFormat
2014-04-17 13:27:13,470 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'currency' of class java.text.DecimalFormatSymbols
2014-04-17 13:27:13,488 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.converters.codecs.XMLCodec$__clinit__closure1
2014-04-17 13:27:13,491 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.codecs.URLCodec$__clinit__closure2
2014-04-17 13:27:13,492 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.codecs.URLCodec$__clinit__closure1
2014-04-17 13:27:13,494 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.codecs.SHA256Codec$__clinit__closure2
2014-04-17 13:27:13,495 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.codecs.SHA256Codec$__clinit__closure1
2014-04-17 13:27:13,498 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.codecs.JavaScriptCodec$__clinit__closure1
2014-04-17 13:27:13,501 DEBUG [org.ehcache.sizeof.ObjectGraphWalker] SizeOf engine walking transient field 'metaClass' of class org.codehaus.groovy.grails.plugins.codecs.MD5BytesCodec$__clinit__closure2

很明显,它遍历了一堆元类,导致它到达其他元类,天知道在哪里结束..

Ehcache 有一种机制来配置此处描述的这种计算大小:http://ehcache.org/documentation/configuration/cache-size#built-in-sizing-computation-and-enforcement

最近我发现从 2.8 版本开始(我使用 2.8.1)还有一个用于此配置的编程 API,您可以使用此库进行设置:https://github.com/Terracotta-OSS/ehcache-sizeofengine

有一个implementation of this size of engine for Groovy 可以解决元类遍历。我试过了,恕我直言,它不起作用 - 它的核心是这个过滤器:

public void configure(final Filter filter) {
    filter.ignoreInstancesOf(groovy.lang.MetaClass.class, false);
}

我认为问题在于 groovy 对象中的 metaClass 字段不是 MetaClass 的实例 - 它在日志中也可见。

所以在这么长的描述之后提出一个问题:

有人遇到过同样的问题并以某种方式解决了吗?

【问题讨论】:

    标签: caching grails groovy ehcache grails-cache


    【解决方案1】:

    如果您使用 https://github.com/alexsnaps/ehcache-sizeofengine-groovy 应该可以解决您的问题。

    不幸的是,它不在 Maven Central 中,因此您需要构建它并将其发布到您的

    【讨论】:

    • 你使用成功了吗?在我的问题中,我提到我使用了这个引擎,但它对我不起作用。它没有解决元类遍历问题..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2012-07-07
    • 2013-11-27
    相关资源
    最近更新 更多