A little tip for those writing any form of “JUnit”:http://www.junit.org tests (this includes functional tests with JWebUnit or any derivative test frameworks based on JUnit).
(The following is cribbed and edited from an Atlassian internal developer update email – kudos to “Charles”:http://fishbowl.pastiche.org for finding and bringing it to internal attention during his attack on improving the performance of our tests. You do test the performance of your unit tests don’t you? :))
The JUnit test runner keeps every TestCase object, including all their instance variables, in memory for the duration of the whole test run. This means that to avoid having tests’ memory usage spiral out of control, *anything* that you assign to an instance variable in the test *must* be nulled out at the end of the test.
For example, if you have a setup like this:

1
2
3
4
5
6
7
8
<pre>
public void setUp()
{
this.mockFoo = new Mock(Foo.class);
this.contentManager = new DefaultContentManager();
this.contentManager.setFoo(mockFoo.proxy());
}
</pre>

You _must_ have remove these references in the corresponding tear-down, so that all the objects you’ve created during the test can become garbage.

1
2
3
4
5
6
7
<pre>
public void tearDown()
{
this.mockFoo = null;
this.contentManager = null;
}
</pre>

Similarly if you assign anything to an instance variable during a test method, you must null it out in a finally block at the end of the method (although if you find yourself doing this, you’re better off with a local variable anyway).
While this isn’t a huge problem when it’s just mock objects, the fact that our unit tests are once again unable to run without expanding the heap leads me to believe that some tests are keeping hold of references to big things like Hibernate configurations and Spring containers.