Reputation: 10043
This is a follow on to a previous question: Using GroovyClassLoader from Java - Classes not GC'd
I was previously loading Groovy classes in a java environment using a custom groovy classloader, and to get them GC'd correctly I had to explicitly clear the meta class registry as so:
for(Class<?> c : groovyClassLoader.getLoadedClasses()) {
GroovySystem.getMetaClassRegistry().removeMetaClass(c);
}
I have now switched to pre-compiling the groovy classes in to a JAR that I am loading via a normal java classloader, and am now seeing the perm gen memory leaks again when I try to re-load the updated classes.
Anyone know if i need to do anything special to get my classes GC'd? I am dynamically adding constructor/methods to some of the groovy at runtime, so assume I still need to clear the metaClassRegistry?
The above code does not work (obviously) as I am no longer using a groovyClassLoader, but I have also tried just iterating the metaClassRegistry and that just returns null for the registry:
def metaClasses = GroovySystem.getMetaClassRegistry().iterator()
while( metaClasses.hasNext()){
def thisGuy = metaClasses.next()
GroovySystem.getMetaClassRegistry().removeMetaClass(thisGuy)
}
Upvotes: 4
Views: 866
Reputation: 10043
It was the same problem, but just needed a different route to get to the MetaClassRegistry. The following code did the job:
def registry = metaClass.getRegistry()
def iterator = registry.iterator()
while ( iterator.hasNext() ){
def mc = iterator.next()
registry.removeMetaClass( mc.getJavaClass() )
}
(note, this is called from one of the compiled groovy classes so is using the same classloader/metaClassRegistry)
Upvotes: 1