34 messages in org.codehaus.groovy.devRe: [groovy-dev] Re: [groovy-user] Me...
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:Re: [groovy-dev] Re: [groovy-user] Memory leaks in GroovyActions...
From:Tim Quinn (Timo@Sun.COM)
Date:Oct 16, 2008 4:15:37 pm
List:org.codehaus.groovy.dev

Jochen Theodorou wrote:

Alex Tkachman schrieb:

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 [...] 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();

I guess that means that the web application loader can not thrown away unless the deamon here stops, because the thread class itself is loaded by that loader.

Maybe I misunderstand what you mean. The bootstrap class loader will load java.lang.Thread. What I saw as I did the memory analysis on this is that the thread's contextClassLoader is the WebappClassLoader, and that is because the thread which creates this one has the WebappClassLoader for its contextClassLoader and the new thread takes its creator's ccl.

Perhaps the logic you described would work for discriminating among the various profiles; I'm nowhere near familiar enough with Groovy to have an opinion about that. But is it reasonable to provide a public API which an application or a container could invoke to close down Groovy in an orderly manner which would include running down this thread? Granted, the developer of a web app deployed to an app server would need to have a ServletContextListener which detects when the web app is stopping and could then invoke the Groovy close-down method. That does not seem to be too much of a burden, considering the complexity of having Groovy deciding itself which profile is in effect.

Just a thought.

- Tim

I remember we had some "on access" action to remove the stalled entries in 1.5.x. How bad would it impact performance if we do it the same way again? I mean calling poll on each modification instead of remove here.

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.

yes, I see it the same way

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

I agree

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.

terminatingit without recreation is bad.... how do you know we still need it? and is that faster than doing polling on our own? Also with a fixed time you still have the same problem on a high load server. The higher the load, the shorter the time would have to be to avoid the problem, but that will not happen, because you have no way to know the load... also what time values would be good?

No... I think we have these profiles:

a) 1 thread, runniing for a while with low memory requirement and then die, one runtime only, runs a short time -> small application such as benchmark b) multiple threads, one runtime only, probably long running -> normal application c) high load, one thread per request, multiple requests at the same time, multiple runtimes, long running probably -> web application d) many runtimes, low load -> web development

for profile (a) we would probably not need to remove any meta classes.. also no thread local stuff would be needed in this case

for (b) we need to, because the application is long running. Many other languages spawn a completely new runtime per thread... I won't suggest that for Groovy, because it is so near Java, and we would like the threads to be able to communicate to each other. On the other hand we kind of do that already with many threadlocals here and there... making one partial runtime per thread would be a small step then.. Anyway, this profileis what 1.6 targets atm

for (c)... would it work on a per request basis, like a php script for example, then we would have nearly the same situation as in (a). But we are in the Java world, meaning the web application sticks around, even if there is one thread per request. The web application may stay around for a while... this is not the situation of the problem I think

(d) is our problem atm, because of the redeploys we get a higher number of runtimes, where most of them are inactive. Of course only the active ones can get a high load, but the inactive ones have to release their memory while they are inactive

for a we could say we start memory management after a specific time only... in case of (a) it is unlikely that many meta classes are created... so even bettter would be to start memory management only after we got a minimum number of meta classes. That is also compatible with (b). Maybe some benchmarks will run just another little bit faster with this if they stay in the area where no memory management is needed... and I guess most benchmarks from the shootout are of that kind.

for (c) and (d) the question is if on high load where all processing power is used if there is any difference between the thread using remove() or us polling per request. If the processor is not on high load, then the Thread version we have now should be the best one, because it utalizes unused processing power.

Well... what I now suggest is quite complicated to implement... and it is maybe just a stupid idea... but what would be if we had different profiles and we could switch between them, maybe have an option to force one such a profile? Basically it is only a question of abstraction, but abstraction takes a little performance away too..

So basically we would maybe have a profile which does not care how many meta classes are there and does not remove them. Then if a certain amount of meta classes is reached we switch to the next profile, which is either using poll() or remove(), maybe with the thread based remove as default and an application can set the polling. Frankly I would use polling as default and let command line programs (or GroovyMain for example) use a flag to set the other profile. Because in that case we assumein general, that we will be used as library, meaning we should not spawn deamon threads. When used from the command line, we know we are allowed to do that, since there will be only one runtime anyway and we are starting the application by ourselfs too. That would automatically and without any configuration solve the problem for glassfish for example too. We could maybe even say that once a groovy generated, main method is called and a certain property/flag is not set yet, that we assume we are in application mode.

At last if there are no other surprises.

Sorry for the long text ;)

bye blackdrag