Why Is Maven So Slow? [Solved]By Roger Keays, 24 October 2012 |
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 Keays is an artist, an engineer, and a student of life. He has no fixed address and has left footprints on 40-something different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, the proper use of semicolons, and finding good food.
|
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
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
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?
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.
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
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.
Brilliant! With 32bit client my build takes 2min, with 64bit server it takes 4min 30sec!
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] ------------------------------------------------------------------------
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
It will work only for 32-bit jvm, because there is no client vm in 64-bit version
this is true only for 32 bit JDKs. 64-bit only only have server JVM included.