Groovy TemplateEngines和OutOfMemory。可能的内存泄漏?

时间:2016-06-23 13:17:51

标签: java groovy

我在使用Java中的Groovy TemplateEngines而不在OOM中运行时遇到了一些麻烦。在创建许多不同的模板时,我觉得在堆上创建了很多脚本 - 然后它们永远不会是垃圾 集。

我使用java 8.使用-Xmx32M运行此代码时,可能有大约3000次迭代。之后是抛出OOM-Error。

这是我的代码:

import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import groovy.text.TemplateEngine;

import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String[] args) throws Exception {
        String groovy = "XX-${i}";

        for (int i = 0; i < (1000000000); i++) {
            TemplateEngine e = new SimpleTemplateEngine();

            Template t = e.createTemplate(groovy);

            Map<String, Object> binding = new HashMap<>();
            binding.put("i", i);

            String res = t.make(binding).toString();

            if (i % 100 == 0) {
                System.out.println("->" + res);
            }
        }
    }
}

我也尝试了不同的变体和ClassLoaded - 但实际上结果总是相同的。由于我无法找到任何当前的问题,我想我错过了一些东西。

有人可以帮助启发我吗?

蒂诺

3 个答案:

答案 0 :(得分:2)

以下是您的问题https://bugs.openjdk.java.net/browse/JDK-8037342

每次解析器运行时,都会根据正在完成的解析次数创建一个新的唯一类。例如,一段时间后,类名看起来像

  

groovy.runtime.metaclass.SimpleTemplateScript4237MetaClass   groovy.runtime.metaclass.SimpleTemplateScript4238MetaClass

一段时间后,ClassLoader的parallelLockMap将填满堆,没有任何东西有资格成为GC&#39; d。这有点像OOM PermGen错误。

答案 1 :(得分:0)

使用Apache Commons Text。快速高效的替代SimpleTemplateEngine的方法。

String templateString, Map binding;
StrSubstitutor sb = new StrSubstitutor(binding);
String value = sb.replace(templateString);

答案 2 :(得分:0)

我已经为这个问题苦苦挣扎了一段时间,现在我想出了解决方法。

只需在运行脚本后调用 clear 即可。

https://gist.github.com/jpozorio/38f26120e6346dfd74cecd7a147028aa