[ https://issues.apache.org/jira/browse/GROOVY-7621?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15097294#comment-15097294 ]
John Wagenleitner commented on GROOVY-7621: ------------------------------------------- I did some testing of the script removing the calls to set the metaclass to null (i.e., no cleanup) and used a 256m max heap size. Using 2.4.5 and master it completed 4000 iterations before OOME. With master+PR220 it did 7000 iterations. And with master+PR220+PR219 the script completed all 1 million iterations. [PR220 - Fix finalizeReference method override for ManagedReference subclasses|https://github.com/apache/groovy/pull/220] [PR219 - GROOVY-7683 - Memory leak when using Groovy as JSR-223 scripting language|https://github.com/apache/groovy/pull/219] Here is the script as tested {code} package bugreport class LeakTest extends GroovyTestCase { void testLeak() { def sampleSchema = [:] sampleSchema.table1 = [column1: [name:'column1', dataType : 'varchar'] , column2: [name:'column2' ,dataType : 'integer']] def propMissing = { metaThings -> def pMissing = null pMissing = { pName -> def innerProp = delegate.hasProperty("outerType") if (!innerProp ){ if (sampleSchema[pName]) { def resolved = "->"+pName resolved.metaClass.propertyMissing = pMissing resolved.metaClass.outerType = "table" resolved.metaClass.outer = pName // metaThings << resolved return resolved } } else if (delegate.outerType == "table") { if (sampleSchema[delegate.outer][pName]) { def resCol = "->"+pName resCol.metaClass.propertyMissing = pMissing resCol.metaClass.outerType = "column" resCol.metaClass.outer = sampleSchema[delegate.outer][pName] // metaThings << resCol return resCol } } else if (delegate.outerType == "column") { // No metaClasses because no more nesting... if ( pName == "dataType" ) { return delegate.outer.dataType } else if ( pName == "name") { return delegate.outer.name } } throw new MissingPropertyException(pName) } return pMissing } def sampleScript = ''' def result = table1.column1.dataType if (!(++counter % 1000)) println "${counter}. ${result}" ''' def gs = new GroovyShell(); def binding = new Binding() binding.counter = 0 def script = gs.parse( sampleScript ) script.setBinding(binding) def needsCleanup = [] script.metaClass.propertyMissing = propMissing(needsCleanup) for ( int i = 0; i < 1000000; i++) { script.run() // if (!(i % 100)) { // needsCleanup ... how to? I tried remove from metaClassRegistry to no avail... // // this gives errro: //Caught: groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.removeMetaClass() is applicable for argument types: (java.lang.String, null) values: [->table1, null] //Possible solutions: removeMetaClass(java.lang.Class) //needsCleanup.each { GroovySystem.metaClassRegistry.removeMetaClass(it,null) } // needsCleanup.each { // it.metaClass = null // } // needsCleanup = [] //.clear() // } } } } {code} > Memory Leak (metaClassRegistry) unable to remove metaClass based on instances > ----------------------------------------------------------------------------- > > Key: GROOVY-7621 > URL: https://issues.apache.org/jira/browse/GROOVY-7621 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime > Affects Versions: 2.3.7 > Environment: Running from Eclipse, JBoss with jdk 1.6 > Reporter: Kimball C Sampson > > I'm using the GroovyScriptEngine in a web server environment where the > scripts are provided properties on-the-fly from database objects. This is > done by implementing script.metaClass.propertyMissing. When I return a > value, I set the metaClass to give the returned value even more > sub-properties. After processing 100k records or so, I run out of memory. I > tried to write code to remove entries from the metaClassRepository, but > there's no way to do it for an object instanced based metaClass. Also, I've > outputed the GroovySystem.metaClassRepository.iterator().size() and it kept > growing. The values are out of scope so they should get garbage collected, > but the metaClasses aren't getting cleaned up. > The workaround to this problem was to implement a groovy Proxy, though, I > liked the metaClass solution better. -- This message was sent by Atlassian JIRA (v6.3.4#6332)