[jira] [Commented] (GROOVY-8113) Groovy script/template engine produce memory leak
[ https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=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] [Updated] (GROOVY-8113) Groovy script/template engine produce memory leak
[ https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Artyom Kravchenko updated GROOVY-8113: -- Attachment: object_explorer.png merged_path.png > 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] [Updated] (GROOVY-8113) Groovy script/template engine produce memory leak
[ https://issues.apache.org/jira/browse/GROOVY-8113?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Artyom Kravchenko updated GROOVY-8113: -- Description: 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. was: 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: {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
[jira] [Created] (GROOVY-8113) Groovy script/template engine produce memory leak
Artyom Kravchenko created GROOVY-8113: - Summary: 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 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: {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} -- This message was sent by Atlassian JIRA (v6.3.15#6346)
[jira] [Created] (GROOVY-7731) OutOfMemoryError starting from groovy-2.4.5 version.
Artyom Kravchenko created GROOVY-7731: - Summary: OutOfMemoryError starting from groovy-2.4.5 version. Key: GROOVY-7731 URL: https://issues.apache.org/jira/browse/GROOVY-7731 Project: Groovy Issue Type: Bug Components: GroovyScriptEngine Affects Versions: 2.4.5 Environment: Ubuntu 14.04, Mac osx 10.11.1 Java openJDK 1.8, Java HotSpot 1.8 Reporter: Artyom Kravchenko I have faced with memory leak as soon as I upgraded groovy from 2.4.4 to the latest version (2.4.5). As I see groovy-2.4.5 version already contains fix for https://issues.apache.org/jira/browse/GROOVY-7591 and uses ClassInfo.class by default. But such fix causes the other memory leak. It is easy to reproduce by simple test: public class ScriptsMemoryLeak { public static void main(String[] args) throws ScriptException { while (true) { ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("groovy"); engine.eval("println 'test'"); } } } I have run this test with -Xmx20m and OutOfMemoryError occurs after about 400 iterations: Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded at sun.misc.URLClassPath$JarLoader.checkResource(URLClassPath.java:771) at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:843) at sun.misc.URLClassPath.getResource(URLClassPath.java:199) at java.net.URLClassLoader$1.run(URLClassLoader.java:364) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:360) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:81) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166) at Script478.run(Script478.groovy:1) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:352) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:153) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at ish.oncourse.server.scripting.ScriptsMemoryLeak.main(ScriptsMemoryLeak.java:21) When I added -Dgroovy.use.classvalue=true (followed advice in https://issues.apache.org/jira/browse/GROOVY-7591 to reactivate use of ClassValue) the leak goes away and my test can works infinitely. Currently I forced to use -Dgroovy.use.classvalue=true option to proper work of my code. Also I have find other task which was already closed (but probably was not fully done): https://issues.apache.org/jira/browse/GROOVY-6704 >From comment I can see that users still faces with the same issue. Can someone please advise me will be this memory leak fixed in groovy. If yes, then when I will be able to get rid "-Dgroovy.use.classvalue=true" from my code -- This message was sent by Atlassian JIRA (v6.3.4#6332)