An automated way to find JUnit tests that are leaking memory

The root of our problem is singletons. But Singletons are hard to break and in the meantime we have a lot of unit tests that use Singletons without trying to clean them up completely in the tearDown () method. I think a good way to detect such tests is to look for memory leaks. If the memory used after tearDown () and System.gc () is larger than when the test was run, either the test leaked or more classes were loaded by the classloader. Is there a way to automatically detect such a problem?

+1


a source to share


6 answers


Could you please imagine a subclass between TestCase and the individual test classes that did the cleanup? Then the subclasses will only be responsible for calling super.teardown () - and only those that have a break ().



+2


a source


I totally agree with other posters that monitoring memory usage is not a viable way of keeping track of this - System.gc () will not behave as you expect, or with sufficient accuracy to accomplish its purpose.

You will need a tool that allows you to inspect the reference graph and display the distribution call stacks.

I have used OptimizeIt from Borland and JProfiler from ej technologies, both with success (a quick google shows that OptimizeIt may now be dead.)



It is also possible to use JVMTI to put together a better monitor for this particular problem.

Edit : Wierd, but when I was reviewing this answer I got a call from Embarcadero, who apparently acquired OptimizeIt, did some update, and is now sold under the name J Optimizer .

+1


a source


Just a thought: if you have two empty tests running right after each other, the second shouldn't have different memory used after teardown (). If so, you (probably) have a leak somewhere in your setup () / teardown () system.

0


a source


I don't think this is a good approach. System.gc()

does not guarantee a complete cleanup of any unused objects you might think.

If your root problem is that you have unit tests that end up using global data (singletons) without fixing it properly, then you should attack the root problem: these unit tests. It shouldn't be too hard to find all tests that don't use tearDown()

, or find all tests that use a particular singleton.

0


a source


If your Singleton is only meant to be initialized once, you can have code that checks for reinitialization and registers the current stack when it detects it. Then, if you inspect the stack, you can see which test got the ball, and you can check the JUnit logs to see the test run before that.

In terms of solving this problem in more detail, rather than discovering it, I would recommend you a singleton initializer that remembers what it initialized and has one break method that rips off whatever it initialized. Thus, tests can only be made to initialize through this class, and only one thing needs to be done in crash mode.

I also think Carl Manaster's suggestion is good, but if you are using JUnit4 then you might have a teardown method that works in a superclass, remember to remember super. If you are not using the JUnit3 GUI, JUnit4 should be a replacement. The only thing to use in your new features that you have to carry over to the whole test, you cannot live in the same class. So tests that interact with these singlons had to be ported one class of tests at a time.

0


a source


You can use Eclipse Memory Analyzer to automate analysis of heap dumps obtained after each test, or probably better after all tests. MAT can automatically detect memory leaks.

0


a source







All Articles