-
Bug
-
Resolution: Fixed
-
Major
-
None
-
Platform: All, OS: All
deadlock.netbeans.org went down with an OOME (with -Xmx400m). Inspection of a
heap dump (442 Mb file!) showed 35Mb worth of Warning and JavaClass instances
from the FB plugin, not counting HashSet's and String's referenced from these
instances. The associated project typically has around 10k warnings, I think.
The heap dump was so big that I was unable to more detailed analysis without my
computer thrashing. Not clear whether there was a true leak - old results kept
in heap incorrectly - or just excessive transient memory consumption. Would
probably need to investigate on a test server with a dummy project.
One thing I noticed in the code - Digester is used to read an XML file, and
probably (did not verify) creates new String's for all the String-valued fields
in Warning and JavaClass. It is very likely many of these strings are identical
and could be shared to significantly reduce memory consumption. Since the
Digester API looks a bit complicated, probably this could be done by interning
String's in the setter methods. Either:
1. Use String.intern. This consumes permgen memory, however, which is dangerous
- it cannot be reclaimed, and few admins would think to set the max permgen size
high.
2. Use a private intern pool, e.g.
// is there an easy, more efficient data structure for this?
static Map<String,String> pool = new HashMap();
static String intern(String s) {
String existing = pool.get(s);
if (existing != null)
else
{ pool.put(s, s); return s; }}
Again, never reclaims memory, but at least uses normal heap.
3. Use a temporary pool which is reset after reading in all data for a build.
(By FindBugsCounter?)