memleak for var declarations in nested functions

Daniel Wunsch <[email protected]> Fri, 1 Jul 2005 03:29:46 +0200
Newsgroups gmane.comp.java.beanshell.devel
Message-ID <[email protected]>
hi there!

debugging a strange memleak in one of my longer-running 
beanshell scripts hprof told me i had megabytes of WeakReference 
objects in memory that at least didn't go away after a few calls to
System#gc.

i discovered that BSHType#getType calls the method
ClassManagerImpl#addListener thousands of times.

the method call
  baseType = ((BSHAmbiguousName)node).toClass(callstack, interpreter );
seems to return null for var declared variables sometimes. in this case,
type is set to null and in later calls to getType, the line
  if ( type != null )
never finds a non-null type, so it registers itself as a Listener again.

you can reproduce this behaviour with bsh-2.0b5-src.jar and the
following code:

// two functions, on in each other
foo() {
	void bar() {
		var	x;	// the inner declares a variable
	}
	return this;
}

// create an object from the outer function
var foo	= foo();

// call the inner function 20 times
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();
foo.bar();

the code within ClassManagerImpl#addListener that should clean up 
the WeakReferences never finds any non-referenced objects, so 
they stay in the Reference queue. i once had about 70.000 of them ;)

if my assumption is correct that
  baseType = ((BSHAmbiguousName)node).toClass(callstack, interpreter );
returns the same value every time its called, then the following diff
contains a fix for the problem. up to now, it seems to work for me.

~/bsh/BeanShell-2.0b5 > 
diff ./src/bsh/BSHType.java-30jun05 ./src/bsh/BSHType.java
58a59,61
>     /** is used by #getType to remember whether type and baseType are 
already set up */
>     private boolean typeCached;
>
62a66
>               typeCached = false;
146c150
<               if ( type != null )
---
>               if ( typeCached )
169a174,175
>
>               typeCached = true;
196a203
>               typeCached = false;

daniel


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click