Bug 30162 - [PATCH] Avoid potential memory leaks from IntrospectionHelper.helpers
Summary: [PATCH] Avoid potential memory leaks from IntrospectionHelper.helpers
Alias: None
Product: Ant
Classification: Unclassified
Component: Core (show other bugs)
Version: 1.6.1
Hardware: All All
: P3 normal with 14 votes (vote)
Target Milestone: 1.7.0
Assignee: Ant Notifications List
Depends on:
Reported: 2004-07-16 23:54 UTC by Jesse Glick
Modified: 2005-03-29 14:48 UTC (History)
2 users (show)

Suggested patch (4.00 KB, patch)
2004-07-16 23:55 UTC, Jesse Glick
Details | Diff
Revised patch for just IntrospectionHelper.java to hold both keys and values weakly in helpers (does not include other classes listed in the previous patch) (2.59 KB, patch)
2004-07-22 22:39 UTC, Jesse Glick
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jesse Glick 2004-07-16 23:54:35 UTC
IntrospectionHelper keeps a cache of helpers it has made for particular Class's.
This cache is cleared (presumably to avoid leaking memory) when the build
finishes - *if* callers have used the factory method IH.getHelper(Project,Class)
rather than the IH.gH(Class) variant. Unfortunately, if you call only
IH.gH(Class) then the Class references are not released, even by a build finish

This appears to have caused a massive memory leak in the JVM permanent
generation (where classes are held) in the NetBeans IDE. (Workaround: forcibly
clear the cache via reflection.) More:

Better would be to use a WeakHashMap, since there is no reason to keep a cache
entry if the Class key is referenced only from that entry; it could not possibly
be used. Generally, please be very suspicious of any static fields, especially
maps, and use weak references wherever appropriate.

Attaching a patch which makes the cache weak on the key, and also uses the 2-arg
variant of getHelper wherever it seems it would be possible. (There are some
places where there is no Project context and it is not possible.)
Comment 1 Jesse Glick 2004-07-16 23:55:11 UTC
Created attachment 12131 [details]
Suggested patch
Comment 2 Jesse Glick 2004-07-22 22:34:31 UTC
My apologies,

private static Map/*<Class,IntrospectionHelper>*/ helpers = new WeakHashMap();

won't help since each IH holds a ref to the Class in the 'bean' field, which
will prevent the Class from being collected.
Comment 3 Jesse Glick 2004-07-22 22:39:04 UTC
Created attachment 12198 [details]
Revised patch for just IntrospectionHelper.java to hold both keys and values weakly in helpers (does not include other classes listed in the previous patch)
Comment 4 Jesse Glick 2004-07-22 22:43:01 UTC
Note that the revised patch lets IntrospectionHelper objects be collected even
while the Class still exists, which may be undesirable since it could result in
too much object recreation. I'm sure there's some trick which ReferenceQueue's
which solves this...
Comment 5 Jesse Glick 2005-03-29 23:31:29 UTC
Revising strategy a bit. I am unfortunately not aware of any way to prevent some
IH objects from being collected on occasion while the Class still exists, since
the IH must retain a reference to the Class (e.g. it holds Method's defined by
it) - and Java provides no way to make two objects live or die as a pair. This
could be problematic for performance. However the rest of the patch should still
at least be an improvement - no one in main Ant code would be calling
IH.gH(Class) any more. IH.gH(Project,Class) will still use a cache, but this is
cleared when any build finishes (not necessarily the one that asked for the IH,
by the way). Interactive environments such as NetBeans do have to call
gh(Class), for purposes of code completion, as there is no associated project -
so these IH instances will not be cached.
Comment 6 Jesse Glick 2005-03-29 23:48:11 UTC
Checking in src/main/org/apache/tools/ant/IntrospectionHelper.java;
/home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v  <-- 
new revision: 1.94; previous revision: 1.93
Checking in src/main/org/apache/tools/ant/ProjectHelper.java;
/home/cvs/ant/src/main/org/apache/tools/ant/ProjectHelper.java,v  <-- 
new revision: 1.115; previous revision: 1.114
Checking in src/main/org/apache/tools/ant/UnknownElement.java;
/home/cvs/ant/src/main/org/apache/tools/ant/UnknownElement.java,v  <-- 
new revision: 1.88; previous revision: 1.87
More commits to come...
Checking in src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java;
/home/cvs/ant/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java,v  <--
new revision: 1.30; previous revision: 1.29
More commits to come...
Checking in src/main/org/apache/tools/ant/taskdefs/AntStructure.java;
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/AntStructure.java,v  <-- 
new revision: 1.44; previous revision: 1.43