groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <blackd...@gmx.org>
Subject Re: Memory leaks, GroovyClassLoader, and the MetaClassRegistry
Date Tue, 02 Jun 2015 12:00:36 GMT
Am 01.06.2015 22:13, schrieb Kyle Boon:
> We have a memory leak that I'm fairly confident that can be traced back
> to this issue:
>
> http://stackoverflow.com/questions/14343393/using-groovyclassloader-from-java-classes-not-gcd

can you tell me Groovy and Java versions as well as if you tried the vm 
switch -XX:+CMSClassUnloadingEnabled ?

> We have a lot of REST services that result in code being compiled and
> executed during the HTTP request.  I'm exploring a few different options
> to try to fix the memory leak by removing the class from the
> MetaClassRegistry which (should) allow the class to be garbage collected
> during the next full GC.  At the end of the request, while there is
> still an instance of the compiled Script class, I could remove the class
> from the MetaClassRegistry explicitly. Or, I could create a background
> job that would find all compiled Script classes and remove them from the
> MetaClassRegistry in bulk.
>
> Complicating this slightly is that in order to reduce the number of
> times we actually need to compile code, we put the compiled class into a
> Guava cache. Then we can avoid the compilation step the majority of the
> time. My question is, what happens if the class is removed from the
> MetaClassRegistry and then another instance of that class is created
> later? Would it be worth it to try to recreate the meta class for the
> script class if it was missing? Or is this just a fool's errand?

It really depends on what meta class you are using here... namely 
MetaClassImpl (default), ExpandoMetaClass or a custom one (which I 
assume you don't do).

The default meta class handling is designed to be able to "loose" the 
meta class and have it automatically recreated at a later point. For 
this all the default meta classes are only reachable through soft 
references. So it is perfectly fine to remove it from the registry. It 
will be recreated on demand... of course that has a performance penalty. 
But you don't have to recreate it manually... actually setting the meta 
class manually can result in the meta class not being soft referenced 
anymore. Also groovy objects store the meta class in a instance field 
(groovy has per instance meta classes). So as long as the script 
instance exists, the meta class usually does as well, unless you null 
the field of course. But the instance is not the problem here I guess.

If ExpandoMetaClass is used (default in Grails), things can be slightly 
different. Here usually strong references are used, if not from the 
beginning, then from the point of mutation of the meta class. Would be 
good to know if we can exclude the ExpandoMetaClass case.

bye blackdrag

-- 
Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/


Mime
View raw message