Patterns in Software

Why Is Maven So Slow? [Solved]

By , 24 October 2012

Why Is Maven So Slow? [Solved]
Why Is Maven So Slow? [Solved]

I couldn't figure out why the heck my maven builds where taking so long. I thought Java was supposed to be fast these days and here I am waiting 30 seconds to run a unit test. So I did some digging and eventually found the problem.

On Linux, the default JVM is the Server JVM which does all sorts of useful optimisations for long running server process but is absolutely dog slow for building source code (this could also be a reason why the Linux community thinks Java sucks so much).

To find out what JVM you are running simply type:

$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)

If you see "Server VM" like the example above do me a favor and time your maven compile (mvn clean compile) then switch to the Client VM, time it again and post your results in the comments below.

Why Is Maven So Slow? [Solved]

Here is my output with the Server VM:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:05.320s
[INFO] Finished at: Tue Oct 23 22:25:44 ECT 2012
[INFO] Final Memory: 19M/197M
[INFO] ------------------------------------------------------------------------

The simplest way to switch to the Client VM is to find and patch jvm.cfg. You can also export MAVEN_OPTS="-client", but unfortunately maven doesn't use these options when forking for unit tests or executing your app so you have to update your pom.xml adding -client to all plugins that fork jvms.

My jvm.cfg is in $JAVA_HOME/jre/lib/i386/jvm.cfg. Edit it and make sure -client KNOWN appears on the first line.

-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR

Now check that it worked.

$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Client VM (build 20.1-b02, mixed mode)

And rebuild your app.

$ mvn clean install
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 22.612s
[INFO] Finished at: Tue Oct 23 22:33:48 ECT 2012
[INFO] Final Memory: 17M/78M
[INFO] ------------------------------------------------------------------------

That's a full three times faster using half the memory.

I just got a few more years life out of my laptop.

 

About Roger Keays

Roger is an active member of the JSF 2 Expert Group and is happy to be a contributor to the Java Community. He has been writing software since the age of 8 and his other interests include languages, science, travel and running.

Comment posted by: Kovica, 2 years ago

 this is true only for 32 bit JDKs. 64-bit only only have server JVM included.

Comment posted by: Zlatan, 2 years ago

It will work only for 32-bit jvm, because there is no client vm in 64-bit version

Comment posted by: Waddle, 2 years ago

You can also stop using clean all the time, it will reduce the compile time by 95%...

You can also stop using install and use a modern IDE, it will give you the last 5% XD

Comment posted by: , 2 years ago

I don't see how having 64bits is going to speed up the server vm. Multiple CPUs might, but it would still be worth downloading the 32bit version to try out the client vm.

I gave JRockit a try and it turns out to be only slightly slower than the client vm but still much faster than the server vm:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 26.087s
[INFO] Finished at: Wed Oct 24 16:41:05 ECT 2012
[INFO] Final Memory: 53M/76M
[INFO] ------------------------------------------------------------------------
Comment posted by: Roger Rabit, 2 years ago

Brilliant! With 32bit client my build takes 2min, with 64bit server it takes 4min 30sec!

Comment posted by: Rohit, 2 years ago

This is something like a find to me. though I mostly run maven build from windows machine except for release and looks i can save some time here.

Comment posted by: Tom, 2 years ago

I had to use OpenJDK 1.7 as my Fedora 16 dist doesn't seem to have a -devel package for 1.6.i686 for some reason.

Using that version of the JDK my build performed the same when using -client or not. I wonder if this is tightened up in later versions of the JDK? For comparison my build on Server VM on Java 6 took an extra minute.

Java 7 client = 2:25

Java 7 server = 2:24

Java 6 server = 3:25

Comment posted by: , 2 years ago

Are you sure you are using the client VM? You need to set -client in MAVEN_OPTS or like I described in the blog. I get similar results with Java 7:

  • Java 7 client = 0:25
  • Java 7 server = 1:21

How many CPUs do you have? My CPU has one core and supports two threads via hyperthreading. That's probably why Java chose the server vm but maybe the hyperthreading slows down the server vm.

Comment posted by: Steve, 4 months ago

I'm running a 64bit server of CENTOS, and it only installs a 64bit version of Java which only comes in Server version. Any ideas on how to start the Server VM with parameters to make it perform like the Client VM?

Comment posted by: dsheta, 3 months ago

Tried this trick with Java 1.7.0_60 and Maven 3.2.2. My project is multi module project.

java -version & mvn --version && time mvn clean package -DskipTests=true                 
                                                                                 
java version "1.7.0_60"                                                                    
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)                                  Java HotSpot(TM) Server VM (build 24.60-b09, mixed mode)                                   
Apache Maven 3.2.2 (45f7c06d68e745d05611f7fd14efb6594181933e; 2014-06-17T19:21:42+05:30)   
Maven home: /root/Downloads/apache-maven-3.2.2                                       Java version: 1.7.0_60, vendor: Oracle Corporation                                         
Java home: /opt/jdk1.7.0_60/jre                                                            
Default locale: en_US, platform encoding: UTF-8                                            
OS name: "linux", version: "2.6.32-131.0.15.el6.i686", arch: "i386", family: "unix" 

 

...............

real    5m35.127s
user    8m9.825s
sys     0m34.304s

After changing to client vm

$ java -version & mvn --version && time mvn clean package -DskipTests=true                               

java version "1.7.0_60"                                                   
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)                      
Java HotSpot(TM) Client VM (build 24.60-b09, mixed mode)                  
.................

real    4m15.052s
user    4m9.389s
sys     0m26.412s

 

It's not significant as it was mentioned in blog, but it shed away more than a minute time from my current build. 

Thanks

 

Comment posted by: dsheta, 3 months ago

Tried this trick with Java 1.7.0_60 and Maven 3.2.2. My project is multi module project.

java -version & mvn --version && time mvn clean package -DskipTests=true                 
                                                                                 
java version "1.7.0_60"                                                                    
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)                                  Java HotSpot(TM) Server VM (build 24.60-b09, mixed mode)                                   
Apache Maven 3.2.2 (45f7c06d68e745d05611f7fd14efb6594181933e; 2014-06-17T19:21:42+05:30)   
Maven home: /root/Downloads/apache-maven-3.2.2                                       Java version: 1.7.0_60, vendor: Oracle Corporation                                         
Java home: /opt/jdk1.7.0_60/jre                                                            
Default locale: en_US, platform encoding: UTF-8                                            
OS name: "linux", version: "2.6.32-131.0.15.el6.i686", arch: "i386", family: "unix" 

 

...............

real    5m35.127s
user    8m9.825s
sys     0m34.304s

After changing to client vm

$ java -version & mvn --version && time mvn clean package -DskipTests=true                               

java version "1.7.0_60"                                                   
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)                      
Java HotSpot(TM) Client VM (build 24.60-b09, mixed mode)                  
.................

real    4m15.052s
user    4m9.389s
sys     0m26.412s

 

It's not significant as it was mentioned in blog, but it shed away more than a minute time from my current build. 

Thanks

 

Add a comment

Please visit http://www.NinthAvenue.com.au/why-is-maven-so-slow to add your comments.

Join The Mailing List

Subscribe to our mailing list for the latest news and announcements.

Follow Ninth Avenue

Website Updates