-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ClassLoader leaks in IndicesCallbackFilter #643
Comments
From mcculls on July 22, 2011 07:31:11 Can you provide a testcase or example code that demonstrates the original problem? Guice trunk has a unit test for proxy class unloading which passes, but perhaps something else is going on in your particular scenario that leads to a leak. A testcase would be useful in identifying the root cause and help verify the patch. |
From adrianosf on July 22, 2011 10:46:51 Here is it. Import both projects in eclipse. When it stops waiting for a key, you may open eclipse MAT or something else and see there are three MyClassLoader instances alive. Note that it shows two problems:
Binary attachments: guice-classloader-leak-test.zip |
From mcculls on July 22, 2011 10:49:35 Thanks, note that the finalizer thread will disappear in the next release (see latest news in issue 288 ) |
From mcculls on July 22, 2011 11:30:24 (No comment was entered for this change.) Owner: mcculls |
From adrianosf on October 02, 2011 19:00:22 Is there any update on this? Is there any chance that my patch or some other fix goes into the next version? |
From sberlin on October 02, 2011 19:54:05 Is it possible for you to add a patch with a test also, ensuring we don't regress in the future? |
From adrianosf on October 03, 2011 03:54:25 I don't see how a test for this could be made, since it will depend on when the garbage collector run. |
From mcculls on October 03, 2011 05:07:27 WRT the suggested patch, it should save the declaring class' hashcode (since this is fixed) and use that in the hashCode method - otherwise you could get a NPE in the CGLIB cache after the class is unloaded. |
From adrianosf on October 04, 2011 04:06:23 Patch updated accordingly to #8 comment. Attachment: gist |
From sberlin on October 07, 2011 06:29:56 Thanks for updating! A test would still be really really awesome. It's possible to force GCs by calling System.gc(), creating large arrays & sleeping. See BytecodeGenTest around line 250 ( https://code.google.com/p/google-guice/source/browse/trunk/core/test/com/googlecode/guice/BytecodeGenTest.java?r=1568#242 ). |
From mcculls on October 27, 2011 16:08:55 Results of further investigation when using the original testcase from #c2 with Guice trunk: adding System.gc() inside the test loop allows GC to collect at least one of the proxy classloaders and all of the test instances and interceptors. This shows that it's not as simple as a stray strong reference causing this leak. Instead the underlying issue seems to be that CGLIB uses a static WeakHashMap in its generator, using the proxy classloader as the weak key and storing details such as the callbacks under the value. Unfortunately WeakHashMaps are only cleared when they mutate - so in this example the callback table will be kept alive until another enhanced class is generated, at which point the map will mutate and the original table will be reclaimed. Adding weak references to IndicesCallbackFilter works around this issue by breaking the indirect link from the WeakHashMap's reference queue back to the proxied class. Note that the callback table will still be held in the map's queue waiting to be reclaimed, but the extra weak references mean the proxy classloader can at least be unloaded. PS: I attempted to extend the BytecodeGenTest to test this scenario, but unfortunately (depending on your perspective) the interceptor classloader is always GC'd. Looks like more work is needed to recreate this as a repeatable unit test. |
From mcculls on October 27, 2011 17:41:24 Here's an alternative patch that also avoids a strong reference to the declaring class or its methods. It uses the MethodWrapper utility class from CGLIB to create keys based on the method signatures - this same utility class is used to de-duplicate the original method list in the Enhancer, so it's safe to use it in the callback filter. Attachment: gist |
From mcculls on October 27, 2011 18:00:19 FYI, I've applied the alternative patch to sisu-guice: sonatype/sisu-guice@f2aae88 so people can try it out with the latest snapshot: https://repository.sonatype.org/content/groups/forge/org/sonatype/sisu/sisu-guice/3.2.0-SNAPSHOT/ |
From sberlin on January 21, 2012 09:57:03 fixed in r1c9b92a5d869 . thanks for the patches everyone! Status: Fixed |
From adrianosf on July 22, 2011 09:51:48
Scenario:
Application loads classes using a URLClassLoader. Modules are loaded from it. There are non-public ImplementedBy classes, but seems to not be the reason for the problems.
Problem:
When I remove all references to URLClassLoader and its classes/instances, Guice maintains references that don't let it go away.
Patch:
Although it probably don't fixes the proxy leaks, it let the URLClassLoader to be released.
The patch is against the 3.0 branch.
Attachment: gist
guice-classloader-leak.diff
Original issue: http://code.google.com/p/google-guice/issues/detail?id=643
The text was updated successfully, but these errors were encountered: