The other day I ran into a problem that made me quite puzzled. I was working on a project which build and ran without any problems. Then I enabled the use of a third-party library during the execution of the tests in the project and suddenly there were out of memory errors in PermGen during the build.
I had changed nothing in my own code and the application were working as expected when being run.
Allocating More PermGen Memory
The first obvious attempt was to allocate more PermGen memory when running the tests using the -XX:MaxPermSize=256m Maven option. In Linux or similar, this is set by executing the following line in a terminal window:
Unfortunately this only delayed the seemingly inevitable out of memory error.
Java 8 and PermGen
If you read this and have the option to build using Java 8 or later, then do try that option. I tried to run my build under Java 8, in which PermGen has been completely removed, and it worked without errors.
Unfortunately I didn’t have the option to use Java 8 so I had to soldier on.
Testing In Isolation
The Maven Surfire plug-in can be configured as to allow multiple tests to be run in parallel and whether a new JVM process is to be started for each new fork or not. In addition you can set memory allocation arguments to be used when running tests.
In the default configuration, tests will not run in parallel and the JVM process in which tests run will be reused. The latter is what may cause PermGen out of memory problems.
By adding the following plug-in configuration to the build section of your Maven pom file, each test will run in a new JVM process and only one single test at a time will be executed:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18.1</version> <configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> <forkCount>1</forkCount> <reuseForks>false</reuseForks> </configuration> </plugin>
With the above configuration in place, the entire build ran without memory problems.
I imagine running tests in parallel can be useful but it will also include additional complexity and problems. One problem that immediately comes to mind is mock servers; each mock server started in parallel would have to listen on a unique port. The Surefire plug-in does have a feature that makes it possible to accomplish but as of today, I am not sure it is worth the effort to parallelize my tests.