当前位置: 首页 > 知识库问答 >
问题:

Grails应用程序中的grails-cache-ehcache插件,用于使用@Cacheable注释进行缓存

姚自强
2023-03-14

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

我的缓存配置为在内存中,如下所示:

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

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

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

我的问题是,当调用这个方法时,我得到了一个< code > Java . lang . out of memory error: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

这里提到了一个Groovy引擎大小的实现,它应该可以解决元类遍历的问题。我试过了,我觉得它不起作用——它的核心是这个过滤器:

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

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

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

是否有人提出了同样的问题并以某种方式解决了它?

共有1个答案

穆轶
2023-03-14

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

然而不幸的是,它不在Maven Central中,所以您需要构建它并将其发布到您的

 类似资料:
  • 如何在Grails 3.0.1中映射带有注释的域类? 以下步骤对我不起作用。 步骤1.我使用Grails 3.0.1创建了一个新应用程序()。 步骤2。如Hibernate注释映射中所述,我在src/main/com/books/Book中创建了一个新类。groovy(也是groovy) 步骤3。然后通过将相关条目添加到grails-app/conf/Hibernate/Hibernate,向Hi

  • 问题内容: 第一部分 在Grails应用程序中,我了解到您可以通过添加以下方式为每个域类启用二级缓存 默认情况下,仅在调用时使用二级缓存,但也可以通过添加到查询将其用于条件查询和动态查找器。 但是,我仍然不确定我是否了解查询缓存的工作原理。我最好的猜测是: 每个域类都有单独的查询缓存,例如一个用于Book,另一个用于Author 在执行类似的查询之前,将根据域类(Author),查询(findBy

  • “grails cf-ush”会导致下面列出的错误。有没有办法使用云铸造插件“重新开始”。我不希望在MySQL数据库和MongoDB数据库中丢失我的测试数据。 严重:错误监听器开始2012年5月18日下午6:31:26组织。阿帕奇。卡塔琳娜。果心StandardContext启动严重:由于之前的错误,Context[]启动失败2012年5月18日下午6:31:26组织。阿帕奇。卡塔琳娜。加载器。W

  • 问题内容: 如何在Grails 3.0.1中使用注释映射域类? 以下步骤对我不起作用。 步骤1 。我使用Grails 3.0.1()创建了一个新应用程序。 第二步 。如“ 使用hibernate注释映射”中所述,我在(也尝试过)中创建了一个新类。 第三步 。然后通过向文件中添加相关条目,向Hibernate sessionFactory注册该类,如下所示: 第四步 。启动应用程序()后,“欢迎使用

  • 在测试应用程序中使用Grails中的JPA注释类(在Grails-3.1.11和Grails-3.2.0上尝试过)有问题。 3.将PostgreSQL JDBC依赖添加到build.grandle: 4、创建新的类DictionaryEntity。src/main/groovy中的groovy: 5、创建Hibernate。cfg。grails app/conf目录中的xml(也尝试了grails

  • 这是我尝试启动应用程序时遇到的错误: