[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak

2021-02-04 Thread Jira


[ 
https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17279013#comment-17279013
 ] 

João Paulo commented on GROOVY-8113:


I have found a workaround for this.

It's not so simple to do and quite ugly to see what was needed to solve this 
issue.

 

Basically, I clean myself all metaclasses after run the script.

The code below use GroovyShell instead of SimpleTemplateEngine, but wok's for 
both cases.

 

In all cases that I was using SimpleTemplateEngine, I have created a cache of 
Template and only reuse it instead of always create a new template.

 

 
{code:java}
Field fieldParallelLockMap = ClassLoader.getDeclaredField('parallelLockMap')
fieldParallelLockMap.setAccessible(true)

final Script groovyScript = new GroovyShell().parse('scriptAsString')
groovyScript.run()

final Class theClass = groovyScript.metaClass.theClass
final String name = theClass.name
ClassLoader classLoader = theClass.classLoader

final ClassLoader parent = classLoader.parent
if (parent != null) {
 ((GroovyClassLoader) parent).removeClassCacheEntry(theClass.name)

 final List classNamesToRemove = 
["groovy.runtime.metaclass.${name}MetaClass".toString(), 
"${name}BeanInfo".toString(), "${name}Customizer".toString()]
 ClassLoader classLoaderToRemoveClasses = classLoader
 while (classLoaderToRemoveClasses != null) {
 final Map parallelLockMap = (Map) 
fieldParallelLockMap.get(classLoaderToRemoveClasses)
 if (parallelLockMap != null) {
 parallelLockMap.entrySet().removeIf { classNamesToRemove.contains(it.key) }
 }
 classLoaderToRemoveClasses = classLoaderToRemoveClasses.parent
 }
}
InvokerHelper.removeClass(theClass){code}
 

> Groovy script/template engine produce memory leak 
> --
>
> Key: GROOVY-8113
> URL: https://issues.apache.org/jira/browse/GROOVY-8113
> Project: Groovy
>  Issue Type: Bug
>  Components: GroovyScriptEngine, Templating
>Affects Versions: 2.4.8
> Environment: Groovy 2.4.8, Oracle Java JDK 8u121
>Reporter: Artyom Kravchenko
>Priority: Critical
> Attachments: merged_path.png, object_explorer.png
>
>
> There is a simple way to produce OutOfMemoryException if  run infinite 
> numbers of groovy scripts or evaluate groovy templates.
> Simple test to reproduce a memory leak(run groovy script and make template 
> inside the script):
> set max heap size: -Xmx7m 
> {code:java}
> import javax.script.*;
> import java.util.HashMap;
> import java.util.Map;
> public class OutOfMemoryTest {
> private static String TEMPLATE = "Dear ${fullName} please go away at 
> ${time}";
> private static String SCRIPT = "def run(args) {\n" +
> "def bindings = ['fullName' : 'Ali Baba', 'time' : new Date()]\n" 
> +
> "println 
> args.templateEngine.createTemplate(args.template).make(bindings).toString()\n"
>  +
> "}";
> public static void main(String... args) {
> //
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> while(true) {
> ScriptEngineManager engineManager = new ScriptEngineManager();
> ScriptEngine engine = engineManager.getEngineByName("groovy");
> try {
> engine.eval(SCRIPT);
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> groovy.text.SimpleTemplateEngine templateEngine = new 
> groovy.text.SimpleTemplateEngine();
> Invocable inv = (Invocable) engine;
> Map params = new HashMap<>();
> params.put("template", TEMPLATE);
> params.put("templateEngine", templateEngine);
> Object[] runArgs = { params };
> try {
> inv.invokeFunction("run", runArgs);
> } catch (ScriptException | NoSuchMethodException e) {
> e.printStackTrace();
> }
> }
> }
> }
> {code}
> The main cause of issue is Java class loader. Two instances: 
> sun.misc.Launcher.AppClassLoader and  sun.misc.Launcher.ExtClassLoader 
> (parent for first one), each of them has a strong reference: 
> {code:java}
> ConcurrentHashMap parallelLockMap
> {code}
> It collects all loaded classes (and never releases their) for application 
> including newly created script/template classes.
> The main reason of introduction of this reference described here:  
> https://blogs.oracle.com/dholmes/entry/parallel_classloading_revisited_fully_concurrent
> For each iteration of my test I see that  parallelLockMap grows with 6 new 
> entries:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> Script94BeanInfo
> Script94Customizer
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> 

[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak

2018-03-20 Thread Artyom Kravchenko (JIRA)

[ 
https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16406298#comment-16406298
 ] 

Artyom Kravchenko commented on GROOVY-8113:
---

Hello [~jkemnade]

My test example written in java not in groovy, so 
"Dear ${fullName} please go away at ${time}";
is String and not GSrting. OutOfMemory.java works ok.

Also I see that the issue still relevant  - I have tested in with 2.4.12 
version.

Could you please confirm that thist issue has the same cause with GROOVY-6655

 

 

> Groovy script/template engine produce memory leak 
> --
>
> Key: GROOVY-8113
> URL: https://issues.apache.org/jira/browse/GROOVY-8113
> Project: Groovy
>  Issue Type: Bug
>  Components: GroovyScriptEngine, Templating
>Affects Versions: 2.4.8
> Environment: Groovy 2.4.8, Oracle Java JDK 8u121
>Reporter: Artyom Kravchenko
>Priority: Major
> Attachments: merged_path.png, object_explorer.png
>
>
> There is a simple way to produce OutOfMemoryException if  run infinite 
> numbers of groovy scripts or evaluate groovy templates.
> Simple test to reproduce a memory leak(run groovy script and make template 
> inside the script):
> set max heap size: -Xmx7m 
> {code:java}
> import javax.script.*;
> import java.util.HashMap;
> import java.util.Map;
> public class OutOfMemoryTest {
> private static String TEMPLATE = "Dear ${fullName} please go away at 
> ${time}";
> private static String SCRIPT = "def run(args) {\n" +
> "def bindings = ['fullName' : 'Ali Baba', 'time' : new Date()]\n" 
> +
> "println 
> args.templateEngine.createTemplate(args.template).make(bindings).toString()\n"
>  +
> "}";
> public static void main(String... args) {
> //
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> while(true) {
> ScriptEngineManager engineManager = new ScriptEngineManager();
> ScriptEngine engine = engineManager.getEngineByName("groovy");
> try {
> engine.eval(SCRIPT);
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> groovy.text.SimpleTemplateEngine templateEngine = new 
> groovy.text.SimpleTemplateEngine();
> Invocable inv = (Invocable) engine;
> Map params = new HashMap<>();
> params.put("template", TEMPLATE);
> params.put("templateEngine", templateEngine);
> Object[] runArgs = { params };
> try {
> inv.invokeFunction("run", runArgs);
> } catch (ScriptException | NoSuchMethodException e) {
> e.printStackTrace();
> }
> }
> }
> }
> {code}
> The main cause of issue is Java class loader. Two instances: 
> sun.misc.Launcher.AppClassLoader and  sun.misc.Launcher.ExtClassLoader 
> (parent for first one), each of them has a strong reference: 
> {code:java}
> ConcurrentHashMap parallelLockMap
> {code}
> It collects all loaded classes (and never releases their) for application 
> including newly created script/template classes.
> The main reason of introduction of this reference described here:  
> https://blogs.oracle.com/dholmes/entry/parallel_classloading_revisited_fully_concurrent
> For each iteration of my test I see that  parallelLockMap grows with 6 new 
> entries:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> Script94BeanInfo
> Script94Customizer
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> See memory snapshots(attached): objects_explorer, merged_path.
> I have found a partial solution of the issue, if I add this code  line to my 
> test:
> {code:java}
>   
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> {code}
> I see that classes like:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> {code}
> goes away (groovy engine don't ask ClassLoader to find this classes on class 
> path therefore such classes are not collected by  ClassLoader) but classes 
> like   
> {code:java}
> Script94BeanInfo
> Script94Customizer
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> still has affect on memory.
> Dear developers, could you please point me any advice/workarounds for this 
> issue. It will be fine to get rig this issue in future releases. 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)


[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak

2018-01-16 Thread Vellington Penjinkilas (JIRA)

[ 
https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16327145#comment-16327145
 ] 

Vellington Penjinkilas commented on GROOVY-8113:


Do we have any solution for this memory ? Getting the same while doing 
GroovyPageTemplateEngine 

> Groovy script/template engine produce memory leak 
> --
>
> Key: GROOVY-8113
> URL: https://issues.apache.org/jira/browse/GROOVY-8113
> Project: Groovy
>  Issue Type: Bug
>  Components: GroovyScriptEngine, Templating
>Affects Versions: 2.4.8
> Environment: Groovy 2.4.8, Oracle Java JDK 8u121
>Reporter: Artyom Kravchenko
>Priority: Major
> Attachments: merged_path.png, object_explorer.png
>
>
> There is a simple way to produce OutOfMemoryException if  run infinite 
> numbers of groovy scripts or evaluate groovy templates.
> Simple test to reproduce a memory leak(run groovy script and make template 
> inside the script):
> set max heap size: -Xmx7m 
> {code:java}
> import javax.script.*;
> import java.util.HashMap;
> import java.util.Map;
> public class OutOfMemoryTest {
> private static String TEMPLATE = "Dear ${fullName} please go away at 
> ${time}";
> private static String SCRIPT = "def run(args) {\n" +
> "def bindings = ['fullName' : 'Ali Baba', 'time' : new Date()]\n" 
> +
> "println 
> args.templateEngine.createTemplate(args.template).make(bindings).toString()\n"
>  +
> "}";
> public static void main(String... args) {
> //
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> while(true) {
> ScriptEngineManager engineManager = new ScriptEngineManager();
> ScriptEngine engine = engineManager.getEngineByName("groovy");
> try {
> engine.eval(SCRIPT);
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> groovy.text.SimpleTemplateEngine templateEngine = new 
> groovy.text.SimpleTemplateEngine();
> Invocable inv = (Invocable) engine;
> Map params = new HashMap<>();
> params.put("template", TEMPLATE);
> params.put("templateEngine", templateEngine);
> Object[] runArgs = { params };
> try {
> inv.invokeFunction("run", runArgs);
> } catch (ScriptException | NoSuchMethodException e) {
> e.printStackTrace();
> }
> }
> }
> }
> {code}
> The main cause of issue is Java class loader. Two instances: 
> sun.misc.Launcher.AppClassLoader and  sun.misc.Launcher.ExtClassLoader 
> (parent for first one), each of them has a strong reference: 
> {code:java}
> ConcurrentHashMap parallelLockMap
> {code}
> It collects all loaded classes (and never releases their) for application 
> including newly created script/template classes.
> The main reason of introduction of this reference described here:  
> https://blogs.oracle.com/dholmes/entry/parallel_classloading_revisited_fully_concurrent
> For each iteration of my test I see that  parallelLockMap grows with 6 new 
> entries:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> Script94BeanInfo
> Script94Customizer
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> See memory snapshots(attached): objects_explorer, merged_path.
> I have found a partial solution of the issue, if I add this code  line to my 
> test:
> {code:java}
>   
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> {code}
> I see that classes like:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> {code}
> goes away (groovy engine don't ask ClassLoader to find this classes on class 
> path therefore such classes are not collected by  ClassLoader) but classes 
> like   
> {code:java}
> Script94BeanInfo
> Script94Customizer
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> still has affect on memory.
> Dear developers, could you please point me any advice/workarounds for this 
> issue. It will be fine to get rig this issue in future releases. 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)


[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak

2017-05-15 Thread Jochen Kemnade (JIRA)

[ 
https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16010340#comment-16010340
 ] 

Jochen Kemnade commented on GROOVY-8113:


or even a duplicate of GROOVY-6655

> Groovy script/template engine produce memory leak 
> --
>
> Key: GROOVY-8113
> URL: https://issues.apache.org/jira/browse/GROOVY-8113
> Project: Groovy
>  Issue Type: Bug
>  Components: GroovyScriptEngine, Templating
>Affects Versions: 2.4.8
> Environment: Groovy 2.4.8, Oracle Java JDK 8u121
>Reporter: Artyom Kravchenko
> Attachments: merged_path.png, object_explorer.png
>
>
> There is a simple way to produce OutOfMemoryException if  run infinite 
> numbers of groovy scripts or evaluate groovy templates.
> Simple test to reproduce a memory leak(run groovy script and make template 
> inside the script):
> set max heap size: -Xmx7m 
> {code:java}
> import javax.script.*;
> import java.util.HashMap;
> import java.util.Map;
> public class OutOfMemoryTest {
> private static String TEMPLATE = "Dear ${fullName} please go away at 
> ${time}";
> private static String SCRIPT = "def run(args) {\n" +
> "def bindings = ['fullName' : 'Ali Baba', 'time' : new Date()]\n" 
> +
> "println 
> args.templateEngine.createTemplate(args.template).make(bindings).toString()\n"
>  +
> "}";
> public static void main(String... args) {
> //
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> while(true) {
> ScriptEngineManager engineManager = new ScriptEngineManager();
> ScriptEngine engine = engineManager.getEngineByName("groovy");
> try {
> engine.eval(SCRIPT);
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> groovy.text.SimpleTemplateEngine templateEngine = new 
> groovy.text.SimpleTemplateEngine();
> Invocable inv = (Invocable) engine;
> Map params = new HashMap<>();
> params.put("template", TEMPLATE);
> params.put("templateEngine", templateEngine);
> Object[] runArgs = { params };
> try {
> inv.invokeFunction("run", runArgs);
> } catch (ScriptException | NoSuchMethodException e) {
> e.printStackTrace();
> }
> }
> }
> }
> {code}
> The main cause of issue is Java class loader. Two instances: 
> sun.misc.Launcher.AppClassLoader and  sun.misc.Launcher.ExtClassLoader 
> (parent for first one), each of them has a strong reference: 
> {code:java}
> ConcurrentHashMap parallelLockMap
> {code}
> It collects all loaded classes (and never releases their) for application 
> including newly created script/template classes.
> The main reason of introduction of this reference described here:  
> https://blogs.oracle.com/dholmes/entry/parallel_classloading_revisited_fully_concurrent
> For each iteration of my test I see that  parallelLockMap grows with 6 new 
> entries:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> Script94BeanInfo
> Script94Customizer
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> See memory snapshots(attached): objects_explorer, merged_path.
> I have found a partial solution of the issue, if I add this code  line to my 
> test:
> {code:java}
>   
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> {code}
> I see that classes like:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> {code}
> goes away (groovy engine don't ask ClassLoader to find this classes on class 
> path therefore such classes are not collected by  ClassLoader) but classes 
> like   
> {code:java}
> Script94BeanInfo
> Script94Customizer
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> still has affect on memory.
> Dear developers, could you please point me any advice/workarounds for this 
> issue. It will be fine to get rig this issue in future releases. 



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak

2017-05-15 Thread Jochen Kemnade (JIRA)

[ 
https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16010045#comment-16010045
 ] 

Jochen Kemnade commented on GROOVY-8113:


maybe related to GROOVY-7083

> Groovy script/template engine produce memory leak 
> --
>
> Key: GROOVY-8113
> URL: https://issues.apache.org/jira/browse/GROOVY-8113
> Project: Groovy
>  Issue Type: Bug
>  Components: GroovyScriptEngine, Templating
>Affects Versions: 2.4.8
> Environment: Groovy 2.4.8, Oracle Java JDK 8u121
>Reporter: Artyom Kravchenko
> Attachments: merged_path.png, object_explorer.png
>
>
> There is a simple way to produce OutOfMemoryException if  run infinite 
> numbers of groovy scripts or evaluate groovy templates.
> Simple test to reproduce a memory leak(run groovy script and make template 
> inside the script):
> set max heap size: -Xmx7m 
> {code:java}
> import javax.script.*;
> import java.util.HashMap;
> import java.util.Map;
> public class OutOfMemoryTest {
> private static String TEMPLATE = "Dear ${fullName} please go away at 
> ${time}";
> private static String SCRIPT = "def run(args) {\n" +
> "def bindings = ['fullName' : 'Ali Baba', 'time' : new Date()]\n" 
> +
> "println 
> args.templateEngine.createTemplate(args.template).make(bindings).toString()\n"
>  +
> "}";
> public static void main(String... args) {
> //
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> while(true) {
> ScriptEngineManager engineManager = new ScriptEngineManager();
> ScriptEngine engine = engineManager.getEngineByName("groovy");
> try {
> engine.eval(SCRIPT);
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> groovy.text.SimpleTemplateEngine templateEngine = new 
> groovy.text.SimpleTemplateEngine();
> Invocable inv = (Invocable) engine;
> Map params = new HashMap<>();
> params.put("template", TEMPLATE);
> params.put("templateEngine", templateEngine);
> Object[] runArgs = { params };
> try {
> inv.invokeFunction("run", runArgs);
> } catch (ScriptException | NoSuchMethodException e) {
> e.printStackTrace();
> }
> }
> }
> }
> {code}
> The main cause of issue is Java class loader. Two instances: 
> sun.misc.Launcher.AppClassLoader and  sun.misc.Launcher.ExtClassLoader 
> (parent for first one), each of them has a strong reference: 
> {code:java}
> ConcurrentHashMap parallelLockMap
> {code}
> It collects all loaded classes (and never releases their) for application 
> including newly created script/template classes.
> The main reason of introduction of this reference described here:  
> https://blogs.oracle.com/dholmes/entry/parallel_classloading_revisited_fully_concurrent
> For each iteration of my test I see that  parallelLockMap grows with 6 new 
> entries:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> Script94BeanInfo
> Script94Customizer
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> See memory snapshots(attached): objects_explorer, merged_path.
> I have found a partial solution of the issue, if I add this code  line to my 
> test:
> {code:java}
>   
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> {code}
> I see that classes like:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> {code}
> goes away (groovy engine don't ask ClassLoader to find this classes on class 
> path therefore such classes are not collected by  ClassLoader) but classes 
> like   
> {code:java}
> Script94BeanInfo
> Script94Customizer
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> still has affect on memory.
> Dear developers, could you please point me any advice/workarounds for this 
> issue. It will be fine to get rig this issue in future releases. 



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak

2017-05-10 Thread Jochen Kemnade (JIRA)

[ 
https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16004154#comment-16004154
 ] 

Jochen Kemnade commented on GROOVY-8113:


I tried to check whether this is still an issue with 2.4.11, but the example 
does not compile:
{code}
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/tmp/groovy-8113.groovy: 8: Apparent variable 'fullName' was found in a static 
scope but doesn't refer to a local variable, static field or class. Possible 
causes:
You attempted to reference a variable in the binding or an instance variable 
from a static context.
You misspelled a classname or statically imported field. Please check the 
spelling.
You attempted to use a method 'fullName' but left out brackets in a place not 
allowed by the grammar.
 @ line 8, column 45.
   atic String TEMPLATE = "Dear ${fullName}
 ^

/tmp/groovy-8113.groovy: 8: Apparent variable 'time' was found in a static 
scope but doesn't refer to a local variable, static field or class. Possible 
causes:
You attempted to reference a variable in the binding or an instance variable 
from a static context.
You misspelled a classname or statically imported field. Please check the 
spelling.
You attempted to use a method 'time' but left out brackets in a place not 
allowed by the grammar.
 @ line 8, column 75.
   {fullName} please go away at ${time}";
 ^

2 errors
{code}

> Groovy script/template engine produce memory leak 
> --
>
> Key: GROOVY-8113
> URL: https://issues.apache.org/jira/browse/GROOVY-8113
> Project: Groovy
>  Issue Type: Bug
>  Components: GroovyScriptEngine, Templating
>Affects Versions: 2.4.8
> Environment: Groovy 2.4.8, Oracle Java JDK 8u121
>Reporter: Artyom Kravchenko
> Attachments: merged_path.png, object_explorer.png
>
>
> There is a simple way to produce OutOfMemoryException if  run infinite 
> numbers of groovy scripts or evaluate groovy templates.
> Simple test to reproduce a memory leak(run groovy script and make template 
> inside the script):
> set max heap size: -Xmx7m 
> {code:java}
> import javax.script.*;
> import java.util.HashMap;
> import java.util.Map;
> public class OutOfMemoryTest {
> private static String TEMPLATE = "Dear ${fullName} please go away at 
> ${time}";
> private static String SCRIPT = "def run(args) {\n" +
> "def bindings = ['fullName' : 'Ali Baba', 'time' : new Date()]\n" 
> +
> "println 
> args.templateEngine.createTemplate(args.template).make(bindings).toString()\n"
>  +
> "}";
> public static void main(String... args) {
> //
> GroovySystem.getMetaClassRegistry().getMetaClassCreationHandler().setDisableCustomMetaClassLookup(true);
> while(true) {
> ScriptEngineManager engineManager = new ScriptEngineManager();
> ScriptEngine engine = engineManager.getEngineByName("groovy");
> try {
> engine.eval(SCRIPT);
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> groovy.text.SimpleTemplateEngine templateEngine = new 
> groovy.text.SimpleTemplateEngine();
> Invocable inv = (Invocable) engine;
> Map params = new HashMap<>();
> params.put("template", TEMPLATE);
> params.put("templateEngine", templateEngine);
> Object[] runArgs = { params };
> try {
> inv.invokeFunction("run", runArgs);
> } catch (ScriptException | NoSuchMethodException e) {
> e.printStackTrace();
> }
> }
> }
> }
> {code}
> The main cause of issue is Java class loader. Two instances: 
> sun.misc.Launcher.AppClassLoader and  sun.misc.Launcher.ExtClassLoader 
> (parent for first one), each of them has a strong reference: 
> {code:java}
> ConcurrentHashMap parallelLockMap
> {code}
> It collects all loaded classes (and never releases their) for application 
> including newly created script/template classes.
> The main reason of introduction of this reference described here:  
> https://blogs.oracle.com/dholmes/entry/parallel_classloading_revisited_fully_concurrent
> For each iteration of my test I see that  parallelLockMap grows with 6 new 
> entries:
> {code:java}
> groovy.runtime.metaclass.Script94MetaClass
> Script94BeanInfo
> Script94Customizer
> groovy.runtime.metaclass.SimpleTemplateScript94MetaClass
> SimpleTemplateScript94BeanInfo
> SimpleTemplateScript94Customizer
> {code}
> See memory snapshots(attached): objects_explorer, merged_path.
> I have found a partial solution of the issue, if I add this code  line to my 
> test:
> {code:java}
>   
>