easyforgood / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

PermGen leak with Mockito and PowerMock #437

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
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   

Original issue reported on code.google.com by petar.pe...@gmail.com on 10 Jun 2013 at 2:30

Attachments:

GoogleCodeExporter commented 8 years ago
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.<init>() line: 32   
    GlobalConfiguration.validate() line: 47 
    MockingProgressImpl.validateMostStuff() line: 82    
    MockingProgressImpl.validateState() line: 69    
    ThreadSafeMockingProgress.validateState() line: 49  
    MockHandlerImpl<T>.handle(Invocation) line: 63  
    NullResultGuardian.handle(Invocation) line: 29  
    InvocationNotifierHandler<T>.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 

Original comment by hen...@akarlsson.com on 26 Jun 2013 at 12:10

GoogleCodeExporter commented 8 years ago
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

Original comment by brice.du...@gmail.com on 13 Nov 2013 at 9:43

GoogleCodeExporter commented 8 years ago
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

Original comment by hen...@devalett.se on 13 Nov 2013 at 4:59

GoogleCodeExporter commented 8 years ago
OK many thanks Henrik

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

Cheers,
Brice

Original comment by brice.du...@gmail.com on 8 Jan 2014 at 1:31