How To Resolve Out Of Memory Issue While Running Powermock Tests

PowerMocks are usually discouraged for unit testing. The reason why PowerMock should be used rarely is, they encourage static methods and variables which are difficult to test. However sometimes it is required in your project to run tests which use Powermock.  Especially if you are dealing with legacy code.

While running PowerMock sometimes I have seen that the build jobs both local and at Jenkins CI server can run out of memory. You may get PermGen out-of-memory Exception. Here are some tips to resolve the problem.

1. Add @PowerMockIgnore on top of the class. Usually when you run the tests with PowerMock, you will have two annotations – @RunWith(PowerMockRunner.class) and @PrepareForTest({list of classes}).

For example you may have the following declaration

@RunWith(PowerMockRunner.class)
 
@PrepareForTest({XMLGeneratorHelper.class})
 
public class XMLGenerator {
 
....
 
}

As you can see the test class needs XMLGeneratorHelper class.  However it may be possible that XMLGeneratorHelper may be using some logging classes or other dependencies.  However these classes may not be required for testing, but they are loaded for each method when tests are executed. When the number of tests are large it can eat up lot of memory in the perm gen and cause out of memory issue.

To solve this add @PowerMockIgnore annotation above the class declaration –

@PowerMockIgnore(value = {list of classes or packages to ignore}).

For example you can declare in the following manner –

@RunWith(PowerMockRunner.class)
 
@PrepareForTest({XMLGeneratorHelper.class})
@PowerMockIgnore(value = {"org.apache.commons.logging.*"})
public class XMLGenerator {
 
....
 
}

2. Increase the Perm Gen size – Perm Gen or Permanent Generation is a memory area in the JVM which is separate from Heap. The permanent generation is used to hold reflective data of the VM itself such as class objects and method objects. These reflective objects are allocated directly into the permanent generation. PowerMock and Mockito load file dynamically into the Perm Gen memory area.

One of the solutions is to increase the permsize. You can increase the size with

set JAVA_OPTS=”-Xms256m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m”.

Notice that the attribute here is MaxPermSize. However remember that if you add more Powermock tests you can run into this issue again.

3.   If you are using maven and run the build using mvn clean deploy you can add perm gen in the jvmArgs tag as follow.

<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.1.10</version>
<configuration>

<jvmArgs>
<arg>-XX:MaxPermSize=1024 -Xms512m -Xmx2048m -XX:PermSize=512m -XX:MaxPermSize=1024m</arg>
</jvmArgs>
</configuration>

4. Last but not the least – consider if you can redesign your class not to use static methods and data.

 

References –

http://stackoverflow.com/questions/1634216/what-is-permsize-in-java
http://stackoverflow.com/questions/11341494/how-do-i-properly-set-the-permgen-size
http://stackoverflow.com/questions/11683196/junit-4-permgen-size-overflow-when-running-tests-in-eclipse-and-maven2