Hi guys,
I would appreciate your help commenting on this issue:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=5104
The Glassfish guys have identified two memory leaks, one of which
results from Guice's use of thread-local storage. They're asking
questions about the Guice codebase. You know a lot more about this
code than I do so I would appreciate your feedback :)
I will post a similar messages in the warp-persist mailing list.
Thanks,
Gili
2008/10/28 Gili <gili.t...@gmail.com>
Hi guys,
I would appreciate your help commenting on this issue:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=5104
The Glassfish guys have identified two memory leaks, one of which
results from Guice's use of thread-local storage. They're asking
questions about the Guice codebase. You know a lot more about this
code than I do so I would appreciate your feedback :)
firstly, which version of guice is being used?
secondly, I would fully expect the current trunk to leak classes on a restart
because the code to allow unloading of proxies is currently disabled due
to issue http://code.google.com/p/google-guice/issues/detail?id=235
Dhanji.
Gili
I tried deploying and undeploying my webapp twice and comparing the two
memory snapshots. That got me nowhere. Now I'm thinking I'll deploy and
undeploy my webapp, take a snapshot and investigate why Guice is still
in memory (since it shouldn't be).
Gili
Gili
Bob Lee wrote:
> Like Jesse said, I think the FRQ thread is the real problem. I don't
> recall a ThreadLocal memory leak in Guice core and would be surprised
> if one ever existed.
>
> Bob
>
> On Mon, Oct 27, 2008 at 11:31 PM, je...@swank.ca
> <mailto:je...@swank.ca> <limpb...@gmail.com
Are you saying the code needs more cleanup before it's ready for commit
or are you saying something else?
> If you want to support web application re-deploying, it will be much
> simpler and safer to just put Guice in your system classpath.
Wouldn't that make things worse? We want to ensure that all
webapp-specific proxies get unloaded when the webapp gets unloaded.
Gili
Are you saying the code needs more cleanup before it's ready for commit
or are you saying something else?
Wouldn't that make things worse? We want to ensure that all
webapp-specific proxies get unloaded when the webapp gets unloaded.
BTW: What's the point of FinalizableReferenceQueue anyway? It's not
like you're doing some sort of disposal once the Reference gets queued.
Why use a ReferenceQueue at all?
Gili
What about the fact that we can hook servlet shutdown? Would it be
possible for FinalizableReferenceQueue's thread to shut down cleanly if
asked?
BTW: What's the point of FinalizableReferenceQueue anyway? It's not
like you're doing some sort of disposal once the Reference gets queued.
Why use a ReferenceQueue at all?
This problem occurs more frequently during development time, but is
actually more critical during production time. Ironically the original
bug report against Glassfish was by people complaining that it was
unacceptable to have to restart the web server every time you wanted to
redeploy your webapp. Apparently it happens often enough to warrant
attention. Also, please consider the implications of running Guice at
the system ClassLoader level: all webapps would have to share the same
Guice instance/version. It would make it difficult to upgrade one webapp
independently of the others. This goes pretty strongly against webapp
"best practices".
That being said, I think we can have our cake and eat it too. Please
take a look at http://forums.sun.com/thread.jspa?messageID=10484065 and
http://java.sun.com/javase/6/docs/api/java/lang/ref/package-summary.html#reachability
The more I read about this, the more I become convinced that ejp is
right. In theory all we'd need to do is have the servlet listener ask
Guice to stop the thread and the remaining References would get
garbage-collected automatically. Yes, this would require you to expose
an extra API function but I think it is quite reasonable when
considering the benefit. I wouldn't expose FinalizableReferenceQueue
either (that's too low-level). Going by the Guice 1.0 API I would
suggest adding Guice.close() that mirrors the way
EntityManagerFactory.close() works. Alternatively you could use
Injector.close() -- I believe others have asked for this anyway to
satisfy other use-cases. Non-servlet users wouldn't have to change anything.
In short: you'd expose a single API call consisting of 2-3 lines of
code (shutting down the thread). In exchange, you'd retain the original
clean implementation of FinalizableReferenceQueue. I know you're not a
fan of exposing a new method but *please* consider the cost/benefit for
us poor web users :)
Thanks,
Gili
That being said, I think we can have our cake and eat it too. Please
take a look at http://forums.sun.com/thread.jspa?messageID=10484065 and
http://java.sun.com/javase/6/docs/api/java/lang/ref/package-summary.html#reachability
In short: you'd expose a single API call consisting of 2-3 lines of
code (shutting down the thread). In exchange, you'd retain the original
clean implementation of FinalizableReferenceQueue. I know you're not a
fan of exposing a new method but *please* consider the cost/benefit for
us poor web users :)
The GC root in this case is the Thread, right? I am saying that if you
shut down the Thread then the application ClassLoader would no longer be
strongly reachable and all associated Soft/WeakReferences and
ReferenceQueue would get garbage-collected properly.
> FRQ is actually in Google Collections, not Guice.
>
> I think I'd use my code above before I'd add a shutDown() method to the
> API...
This issue affects more than just Guice. Any code depending on Google
Collections would potentially suffer from this memory leak while running
under a web container. Look, I don't understand the reluctance. Did I
fail to provide a good use-case? Did I say something wrong?
je...@swank.ca wrote:
> We're sympathetic. I don't like the idea of Guice having consequences
> on deployment. Or redeployment.
>
> Perhaps we could clean up the FRQ code by moving classloading to its
> own helper class. This would make that code testable, and perhaps
> worthy of inclusion...
I would really appreciate any effort you make to this end. Please let
me know if there is anything more I can do to help.
Thank you,
Gili
Also, to my knowledge, Guice does not have a ThreadLocal leak, despite accusations to the contrary in this thread and the Glassfish thread.
Bob Lee wrote:Wouldn't that make things worse? We want to ensure that all
> If you want to support web application re-deploying, it will be much
> simpler and safer to just put Guice in your system classpath.
webapp-specific proxies get unloaded when the webapp gets unloaded.
Gili
This issue affects more than just Guice. Any code depending on Google
Collections would potentially suffer from this memory leak while running
under a web container. Look, I don't understand the reluctance. Did I
fail to provide a good use-case? Did I say something wrong?
Bob
your current solution relies on reading the classfile from the current classloader
by using getResourceAsStream(), but I don't think this is guaranteed to work in
all situations - a safer solution would be to use ASM to generate the bytecode
at runtime (downside: even more code and less readable)
but then again, the ASM generated class could be very simple, perhaps just
a loop that calls a Callable<Boolean> object passed in via the constructor?
PS: Should I try rebuilding this code on my end or were you planning to
clean up it further and cut a snapshot release?
Thank you,
Gili
My main objection to the new implementation is the complexity
factor, it's much more prone to subtle bugs. Let's give it a try anyway.
If it works then everyone is happy, if not we can try something else.
PS: Should I try rebuilding this code on my end or were you planning to
clean up it further and cut a snapshot release?