34 messages in org.codehaus.groovy.dev[groovy-dev] Re: [groovy-user] Memory...
FromSent OnAttachments
Alex TkachmanOct 16, 2008 2:30 pm 
Alex TkachmanOct 16, 2008 3:17 pm 
Jochen TheodorouOct 16, 2008 3:49 pm 
Tim QuinnOct 16, 2008 4:15 pm 
Alexander VeitOct 16, 2008 4:34 pm 
Jochen TheodorouOct 16, 2008 4:43 pm 
Tim QuinnOct 16, 2008 5:28 pm 
Jochen TheodorouOct 17, 2008 6:35 am 
Alex TkachmanOct 17, 2008 6:44 am 
Graeme RocherOct 17, 2008 6:54 am 
Jochen TheodorouOct 17, 2008 7:05 am 
Graeme RocherOct 17, 2008 7:14 am 
alex...@gmail.comOct 17, 2008 7:30 am 
Jochen TheodorouOct 17, 2008 7:36 am 
Alex TkachmanOct 17, 2008 9:51 am 
Jochen TheodorouOct 22, 2008 5:27 am 
Alex TkachmanOct 22, 2008 5:37 am 
Jochen TheodorouOct 22, 2008 6:05 am 
Alex TkachmanOct 22, 2008 6:08 am 
Jochen TheodorouOct 22, 2008 6:18 am.zip
Alex TkachmanOct 22, 2008 6:32 am 
Jochen TheodorouOct 22, 2008 7:06 am 
Guillaume LaforgeOct 22, 2008 7:08 am 
Alex TkachmanOct 22, 2008 7:11 am 
Guillaume LaforgeOct 22, 2008 7:21 am 
Jochen TheodorouOct 22, 2008 7:22 am 
Jochen TheodorouOct 22, 2008 7:39 am 
Jochen TheodorouOct 22, 2008 7:41 am 
Alex TkachmanOct 22, 2008 9:16 am 
Jochen TheodorouOct 22, 2008 10:11 am 
Jochen TheodorouOct 22, 2008 11:24 am 
Alex TkachmanOct 22, 2008 11:48 am 
Jochen TheodorouOct 22, 2008 2:07 pm 
Jochen TheodorouDec 22, 2008 12:52 pm 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[groovy-dev] Re: [groovy-user] Memory leaks in GroovyActions
From:Alex Tkachman (alex@gmail.com)
Date:Oct 16, 2008 2:30:16 pm
List:org.codehaus.groovy.dev

I redirect this thread to dev list because we have important issue here.

Groovy runtime starts demon-thead, which is very important reference handler for many internal data structures. See org.codehaus.groovy.util.FinalizableRef

Here is important part of the code

interface FinalizableRef { .............

public static final ReferenceQueue finalizableQueue = new MyReferenceQueue();

public static abstract class SoftRef<T> extends SoftReference<T> implements FinalizableRef { public SoftRef(T referent) { super(referent, finalizableQueue); }

public void finalizeRef () { } }

public static class MyReferenceQueue extends ReferenceQueue { public MyReferenceQueue() { Thread thread = new Thread() { public void run() { while (true) { try { final FinalizableRef ref = (FinalizableRef) remove(); ref.finalizeRef(); } catch (Throwable t) {// } } } }; thread.setDaemon(true); thread.setName(FinalizableRef.class.getName()); thread.start(); } } }

When we first time load class implementing FinalizableRef we start demon thread, which never ends and in case of GlassFish keeps reference to WebappClassLoader. As I understand each WebappClassLoader has it is own Groovy runtime.

We can't recommend to put Groovy in to server class path as in this case EMC.enableGlobally will effect too wide scope.

The soulution I have in mind is terminate this thread if it removed nothing from queue during some fixed period of time - let say 30seconds - and recreate it on demand again if needed.

What do you think?

On Thu, Oct 16, 2008 at 10:38 PM, Jose Noheda <jose@gmail.com> wrote:

I'm copying some comments from one of the members of the GFv3 team. These result from upgrading the WAR to 1.6beta2

*The memory analysis still suggests that groovy is contributing to the leak but now in a different way. In 1.5.6 the memory analyzer pointed to ThreadLocal storage that groovy created. (The groovy folks pointed out that the thread local storage they create in 1.5.6 uses SoftReferences so that should not be an issue. But in my investigation it looked like a cache that groovy maintains parallel to the TLS was not cleared.) Now groovy 1.6. beta 2 is starting a new daemon thread with each app deployment and the contextClassLoader for those threads is a WebappClassLoader, so the loader can never be reclaimed.

I do not know if groovy has some way to stop those threads as part of an orderly groovy shutdown (if there is such a thing - I don't know groovy well enough to say one way or the other) or how that would be triggered as part of an undeployment. But if the memory analysis is correct this remains an issue for us in 1.6 beta 2 of groovy, just in a different way compared to 1.5.6.*

Does it give you any clues?

Regards,

On Thu, Oct 16, 2008 at 9:09 AM, Jose Noheda <jose@gmail.com>wrote:

Hi, Here's most elaborate response from the list. They recommend us to test with the 1.6 beta version as well (has some fixes around the topic). I'm trying with it and putting it in the server lib folder. In addition to Groovy do you want any other libs moved there?

And thank you very much for the work on the issue.

Regards,

---------- Forwarded message ---------- From: Jochen Theodorou <blac@gmx.org> Date: Wed, Oct 15, 2008 at 7:44 PM Subject: Re: [groovy-user] Memory leaks in Groovy To: us@groovy.codehaus.org

Jose Noheda schrieb:

Hi,

As part of FishCAT (the Glassfish v3 Prelude quality program) we are inspecting some weird memory leaks that happen after some re-deploys of a web application. You can see the issue at https://glassfish.dev.java.net/issues/show_bug.cgi?id=6082.

The Glassfish team has worked very hard with it and some paths point to Groovy compiled classes as a possible culprit (among others). I'm attaching their reasonings along the memory leak trace. I'm attaching a sample Groovy class as well (the rest are very similar). The tests were run using Groovy 1.5.6 (groovy-all), packaged inside a WAR. The class was compiled using a Netbeans 6.5 nightly.

I think it would be of great help if people from this list could take a quick look at the problem and give an opinion even if farfetched.

ok, let us try to get a little forward on this one... the thread local storage (TLS) is a weak hashmap. That means that the keys are weak referenced, but the values are soft referenced and they have hard links to the classes, which are the weak referenced keys. So in the end the keys are to be seen as if they are soft referenced.

So as long as there is memory the TLS will increase... it was mentioned there, that they saw the application taking much memory and then freeing it in the permgen... this sounds very much like what you get for soft reference.

If I for example execute this program:

def script = ''' def foo(){1} 1+foo() ''' def registry = GroovySystem.metaClassRegistry 100000.times { if (it%100==0) { println soft meta classes: ${registry.weakMetaClasses.size()}" } def shell = new GroovyShell() assert shell.evaluate(script) == 2 }

then I get 10-11 soft meta classes, but each iteration creates a new groovy class. So they must be collected. If I use for example this script:

def script = ''' def foo(){1} 1+foo() ''' def registry = GroovySystem.metaClassRegistry def loader = new GroovyClassLoader(this.class.classLoader) 100000.times { if (it%100==0) { println "weak meta classes: ${registry.weakMetaClasses.size()}" } assert loader.parseClass(script).newInstance().run() == 2 }

then the classes remain referenced, because the GroovyClassLoader is holding them and each iteration shows a higher count of meta classes, because the classes are not collected. In fact you still get several thousand iterations this way, because the meta class might be collected even if the class is not. The meta class has its own soft reference and can be collected by itself. So first thing is you run in a permgen problem, because the classes are still here.

inner classes are mentioned... the only case Groovy creates them is when closures are used... so let us extend the script a little:

def script = ''' def foo(){1} def c = {foo()} 1+c() '''

now the count rises much faster, but there is still no problem. The script you gave seems not to produce any inner classes too.

So I still think that there is somewhere a classloader that is hard linked. since you use no class loaders from GroovyI doubt Groovy has really a problem here...just in case... is it possible for you to update to 1.5.7? I don't think we fixed any important bug that may affect this, but who knows.

bye blackdrag