Export to GitHub

mockito - issue #437

PermGen leak with Mockito and PowerMock


Posted on Jun 10, 2013 by Swift Ox

What steps will reproduce the problem? There is a memory leak with using powermock and mockito with static mocks.

  1. Import the attached project in Eclipse - it contains two classes together with two test classes.
  2. Put a breakpoint in ThreadSafeMockingProgress.threadSafely() line 23.
  3. Start debugging as Junit on the src/test/java folder - this will effectively execute the two test classes.
  4. First time you hit the breakpoint is when the static mock is called - just continue
  5. On the second hit, examine the stack trace

What is the expected output? What do you see instead? The stack trace will show that the org.mockito.internal.progress.ThreadSafeMockingProgress.threadSafely() method is called in the Finalizer thread when the mock object is being finalized. This causes an instance of MockingProgressImpl to be put in a thread local. Since the MockingProgressImpl class is loaded by the PowerMock classloader, this will effectively cause a leak of this classloader. If you have many tests using PowerMock this will eventually lead to an OOM for PermGen space.

What version of the product are you using? On what operating system? Mockito 1.9.5 Powermock 1.5

Please provide any additional information below. Here is a stack trace showing the problem:

Daemon System Thread [Finalizer] (Suspended (breakpoint at line 23 in ThreadSafeMockingProgress))
ThreadSafeMockingProgress.threadSafely() line: 23
ThreadSafeMockingProgress.pullVerificationMode() line: 41
MockHandlerImpl<T>.handle(Invocation) line: 56
NullResultGuardian.handle(Invocation) line: 29
InvocationNotifierHandler<T>.handle(Invocation) line: 38
MethodInterceptorFilter.intercept(Object, Method, Object[], MethodProxy) line: 51
StaticCalculator$$EnhancerByMockitoWithCGLIB$$63e95cb9.finalize() line: not available
Finalizer.invokeFinalizeMethod(Object) line: not available [native method]
Finalizer.runFinalizer() line: 83
Finalizer.access$100(Finalizer) line: 14
Finalizer$FinalizerThread.run() line: 160

Attachments

Comment #1

Posted on Jun 26, 2013 by Grumpy Bear

The same problem also occurs in the class GlobalConfiguration. If you analyze the thread dump after a PermGen Out Of Memory exception, you will find instances of org.mockito.configuration.DefaultMockitoConfiguration (along with instances of org.mockito.internal.progress.MockingProgressImpl, described above).

This is because new DefaultMockitoConfigurations are created by the finalizer thread in the class GlobalConfiguration, same problem as desribed above. You can reuse the same test case as above, but put a breakpoint in GlobalConfiguration.createConfig() line 37 instead.

Please see the stack trace for this problem below:

Daemon System Thread [Finalizer] (Suspended (breakpoint at line 37 in GlobalConfiguration)) GlobalConfiguration.createConfig() line: 37 GlobalConfiguration.() line: 32
GlobalConfiguration.validate() line: 47 MockingProgressImpl.validateMostStuff() line: 82
MockingProgressImpl.validateState() line: 69
ThreadSafeMockingProgress.validateState() line: 49
MockHandlerImpl.handle(Invocation) line: 63
NullResultGuardian.handle(Invocation) line: 29
InvocationNotifierHandler.handle(Invocation) line: 38
MethodInterceptorFilter.intercept(Object, Method, Object[], MethodProxy) line: 51
StaticCalculator$$EnhancerByMockitoWithCGLIB$$33b925ba.finalize() line: not available
Finalizer.invokeFinalizeMethod(Object) line: not available [native method]
Finalizer.runFinalizer() line: not available
Finalizer.access$100(Finalizer) line: not available
Finalizer$FinalizerThread.run() line: not available

Comment #2

Posted on Nov 13, 2013 by Happy Horse

Hi,

Wow pretty deep stuff, Powermock is not maintained here, but I'm curious as to why our objects are created in the Finalizer thread.

@Henrik the leak with GlobalConfiguration happens with the Mockito + Powermock combination ?

Is it reproducible without Powermock ?

Anyway I'm just reading the issue, I don't yet see how to fix that, and the team is open to suggestions.

Cheers, Brice

Comment #3

Posted on Nov 13, 2013 by Swift Horse

Hi Brice,

The problem should only occur when using Mockito + Powermock together. I have created a patch in Powermock to solve it, please see https://code.google.com/p/powermock/issues/detail?id=207#c39. This will be included in the next released version of Powermock (http://powermock.googlecode.com/svn/trunk/changelog.txt).

Thanks and regards, Henrik

Comment #4

Posted on Jan 8, 2014 by Happy Horse

OK many thanks Henrik

I'll mark this issue as invalid since the patch is on the Powermock code base.

Cheers, Brice

Status: Invalid

Labels:
Type-Defect Priority-Medium Memoryleak