[ 
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)

Reply via email to