[java] Real differences between "java -server" and "java -client"?

Is there any real practical difference between "java -server" and "java -client"?

All I can find on Sun's site is a vague

"-server starts slower but should run faster".

What are the real differences? (Using JDK 1.6.0_07 currently.)

This question is related to java jvm jvm-hotspot

The answer is


the -client and -server systems are different binaries. They are essentially two different compilers (JITs) interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs

enter image description here

We run the following code with both switches:

package com.blogspot.sdoulger;

public class LoopTest {
    public LoopTest() {
        super();
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        spendTime();
        long end = System.currentTimeMillis();
        System.out.println("Time spent: "+ (end-start));

        LoopTest loopTest = new LoopTest();
    }

    private static void spendTime() {
        for (int i =500000000;i>0;i--) {
        }
    }
}

Note: The code is been compiled only once! The classes are the same in both runs!

With -client:
java.exe -client -classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
Time spent: 766

With -server:
java.exe -server -classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
Time spent: 0

It seems that the more aggressive optimazation of the server system, remove the loop as it understands that it does not perform any action!

Reference


IIRC, it involves garbage collection strategies. The theory is that a client and server will be different in terms of short-lived objects, which is important for modern GC algorithms.

Here is a link on server mode. Alas, they don't mention client mode.

Here is a very thorough link on GC in general; this is a more basic article. Not sure if either address -server vs -client but this is relevant material.

At No Fluff Just Stuff, both Ken Sipe and Glenn Vandenburg do great talks on this kind of thing.


From Goetz - Java Concurrency in Practice:

  1. Debugging tip: For server applications, be sure to always specify the -server JVM command line switch when invoking the JVM, even for development and testing. The server JVM performs more optimization than the client JVM, such as hoisting variables out of a loop that are not modified in the loop; code that might appear to work in the development environment (client JVM) can break in the deployment environment (server JVM). For example, had we “forgotten” to declare the variable asleep as volatile in Listing 3.4, the server JVM could hoist the test out of the loop (turning it into an infinite loop), but the client JVM would not. An infinite loop that shows up in development is far less costly than one that only shows up in production.

Listing 3.4. Counting sheep.

volatile boolean asleep; ... while (!asleep) countSomeSheep();

My emphasis. YMMV


Oracle’s online documentation provides some information for Java SE 7.

On the java – the Java application launcher page for Windows, the -client option is ignored in a 64-bit JDK:

Select the Java HotSpot Client VM. A 64-bit capable jdk currently ignores this option and instead uses the Java HotSpot Server VM.

However (to make things interesting), under -server it states:

Select the Java HotSpot Server VM. On a 64-bit capable jdk only the Java HotSpot Server VM is supported so the -server option is implicit. This is subject to change in a future release.

The Server-Class Machine Detection page gives information on which VM is selected by OS and architecture.

I don’t know how much of this applies to JDK 6.


IIRC, it involves garbage collection strategies. The theory is that a client and server will be different in terms of short-lived objects, which is important for modern GC algorithms.

Here is a link on server mode. Alas, they don't mention client mode.

Here is a very thorough link on GC in general; this is a more basic article. Not sure if either address -server vs -client but this is relevant material.

At No Fluff Just Stuff, both Ken Sipe and Glenn Vandenburg do great talks on this kind of thing.


One difference I've just noticed is that in "client" mode, it seems the JVM actually gives some unused memory back to the operating system, whereas with "server" mode, once the JVM grabs the memory, it won't give it back. Thats how it appears on Solaris with Java6 anyway (using prstat -Z to see the amount of memory allocated to a process).


IIRC the server VM does more hotspot optimizations at startup so it runs faster but takes a little longer to start and uses more memory. The client VM defers most of the optimization to allow faster startup.

Edit to add: Here's some info from Sun, it's not very specific but will give you some ideas.


When doing a migration from 1.4 to 1.7("1.7.0_55") version.The thing that we observed here is, there is no such differences in default values assigned to heapsize|permsize|ThreadStackSize parameters in client & server mode.

By the way, (http://www.oracle.com/technetwork/java/ergo5-140223.html). This is the snippet taken from above link.

initial heap size of 1/64 of physical memory up to 1Gbyte
maximum heap size of ¼ of physical memory up to 1Gbyte

ThreadStackSize is higher in 1.7, while going through Open JDK forum,there are discussions which stated frame size is somewhat higher in 1.7 version. It is believed real difference could be possible to measure at run time based on your behavior of your application


Last time I had a look at this, (and admittedly it was a while back) the biggest difference I noticed was in the garbage collection.

IIRC:

  • The server heap VM has a differnt number of generations than the Client VM, and a different garbage collection algorithm. This may not be true anymore
  • The server VM will allocate memory and not release it to the OS
  • The server VM will use more sophisticated optimisation algorithms, and hence have bigger time and memory requirements for optimisation

If you can compare two java VMs, one client, one server using the jvisualvm tool, you should see a difference in the frequency and effect of the garbage collection, as well as in the number of generations.

I had a pair of screenshots that showed the difference really well, but I can't reproduce as I have a 64 bit JVM which only implements the server VM. (And I can't be bothered to download and wrangle the 32 bit version on my system as well.)

This doesn't seem to be the case anymore, having tried running some code on windows with both server and client VMs, I seem to get the same generation model for both...


I've not noticed any difference in startup time between the 2, but clocked a very minimal improvement in application performance with "-server" (Solaris server, everyone using SunRays to run the app). That was under 1.5.


the -client and -server systems are different binaries. They are essentially two different compilers (JITs) interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs

enter image description here

We run the following code with both switches:

package com.blogspot.sdoulger;

public class LoopTest {
    public LoopTest() {
        super();
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        spendTime();
        long end = System.currentTimeMillis();
        System.out.println("Time spent: "+ (end-start));

        LoopTest loopTest = new LoopTest();
    }

    private static void spendTime() {
        for (int i =500000000;i>0;i--) {
        }
    }
}

Note: The code is been compiled only once! The classes are the same in both runs!

With -client:
java.exe -client -classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
Time spent: 766

With -server:
java.exe -server -classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
Time spent: 0

It seems that the more aggressive optimazation of the server system, remove the loop as it understands that it does not perform any action!

Reference


Last time I had a look at this, (and admittedly it was a while back) the biggest difference I noticed was in the garbage collection.

IIRC:

  • The server heap VM has a differnt number of generations than the Client VM, and a different garbage collection algorithm. This may not be true anymore
  • The server VM will allocate memory and not release it to the OS
  • The server VM will use more sophisticated optimisation algorithms, and hence have bigger time and memory requirements for optimisation

If you can compare two java VMs, one client, one server using the jvisualvm tool, you should see a difference in the frequency and effect of the garbage collection, as well as in the number of generations.

I had a pair of screenshots that showed the difference really well, but I can't reproduce as I have a 64 bit JVM which only implements the server VM. (And I can't be bothered to download and wrangle the 32 bit version on my system as well.)

This doesn't seem to be the case anymore, having tried running some code on windows with both server and client VMs, I seem to get the same generation model for both...


One difference I've just noticed is that in "client" mode, it seems the JVM actually gives some unused memory back to the operating system, whereas with "server" mode, once the JVM grabs the memory, it won't give it back. Thats how it appears on Solaris with Java6 anyway (using prstat -Z to see the amount of memory allocated to a process).


I've not noticed any difference in startup time between the 2, but clocked a very minimal improvement in application performance with "-server" (Solaris server, everyone using SunRays to run the app). That was under 1.5.


IIRC the server VM does more hotspot optimizations at startup so it runs faster but takes a little longer to start and uses more memory. The client VM defers most of the optimization to allow faster startup.

Edit to add: Here's some info from Sun, it's not very specific but will give you some ideas.


The most visible immediate difference in older versions of Java would be the memory allocated to a -client as opposed to a -server application. For instance, on my Linux system, I get:

$ java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 66328448         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 1063256064       {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 16777216         {pd product}
java version "1.6.0_24"

as it defaults to -server, but with the -client option I get:

$ java -client -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 16777216         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 268435456        {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 12582912         {pd product}
java version "1.6.0_24"

so with -server most of the memory limits and initial allocations are much higher for this java version.

These values can change for different combinations of architecture, operating system and jvm version however. Recent versions of the jvm have removed flags and re-moved many of the distinctions between server and client.

Remember too that you can see all the details of a running jvm using jvisualvm. This is useful if you have users who or modules which set JAVA_OPTS or use scripts which change command line options. This will also let you monitor, in real time, heap and permgen space usage along with lots of other stats.


IIRC, it involves garbage collection strategies. The theory is that a client and server will be different in terms of short-lived objects, which is important for modern GC algorithms.

Here is a link on server mode. Alas, they don't mention client mode.

Here is a very thorough link on GC in general; this is a more basic article. Not sure if either address -server vs -client but this is relevant material.

At No Fluff Just Stuff, both Ken Sipe and Glenn Vandenburg do great talks on this kind of thing.


From Goetz - Java Concurrency in Practice:

  1. Debugging tip: For server applications, be sure to always specify the -server JVM command line switch when invoking the JVM, even for development and testing. The server JVM performs more optimization than the client JVM, such as hoisting variables out of a loop that are not modified in the loop; code that might appear to work in the development environment (client JVM) can break in the deployment environment (server JVM). For example, had we “forgotten” to declare the variable asleep as volatile in Listing 3.4, the server JVM could hoist the test out of the loop (turning it into an infinite loop), but the client JVM would not. An infinite loop that shows up in development is far less costly than one that only shows up in production.

Listing 3.4. Counting sheep.

volatile boolean asleep; ... while (!asleep) countSomeSheep();

My emphasis. YMMV


IIRC the server VM does more hotspot optimizations at startup so it runs faster but takes a little longer to start and uses more memory. The client VM defers most of the optimization to allow faster startup.

Edit to add: Here's some info from Sun, it's not very specific but will give you some ideas.


IIRC, it involves garbage collection strategies. The theory is that a client and server will be different in terms of short-lived objects, which is important for modern GC algorithms.

Here is a link on server mode. Alas, they don't mention client mode.

Here is a very thorough link on GC in general; this is a more basic article. Not sure if either address -server vs -client but this is relevant material.

At No Fluff Just Stuff, both Ken Sipe and Glenn Vandenburg do great talks on this kind of thing.


The most visible immediate difference in older versions of Java would be the memory allocated to a -client as opposed to a -server application. For instance, on my Linux system, I get:

$ java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 66328448         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 1063256064       {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 16777216         {pd product}
java version "1.6.0_24"

as it defaults to -server, but with the -client option I get:

$ java -client -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 16777216         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 268435456        {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 12582912         {pd product}
java version "1.6.0_24"

so with -server most of the memory limits and initial allocations are much higher for this java version.

These values can change for different combinations of architecture, operating system and jvm version however. Recent versions of the jvm have removed flags and re-moved many of the distinctions between server and client.

Remember too that you can see all the details of a running jvm using jvisualvm. This is useful if you have users who or modules which set JAVA_OPTS or use scripts which change command line options. This will also let you monitor, in real time, heap and permgen space usage along with lots of other stats.


I've not noticed any difference in startup time between the 2, but clocked a very minimal improvement in application performance with "-server" (Solaris server, everyone using SunRays to run the app). That was under 1.5.


IIRC the server VM does more hotspot optimizations at startup so it runs faster but takes a little longer to start and uses more memory. The client VM defers most of the optimization to allow faster startup.

Edit to add: Here's some info from Sun, it's not very specific but will give you some ideas.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to jvm

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 How can I get a random number in Kotlin? Kotlin unresolved reference in IntelliJ Is JVM ARGS '-Xms1024m -Xmx2048m' still useful in Java 8? Android Gradle Could not reserve enough space for object heap Android java.exe finished with non-zero exit value 1 Android Studio Gradle project "Unable to start the daemon process /initialization of VM" Android Studio - No JVM Installation found Android Studio error: "Environment variable does not point to a valid JVM installation" Installing Android Studio, does not point to a valid JVM installation error

Examples related to jvm-hotspot

Class JavaLaunchHelper is implemented in both ... libinstrument.dylib. One of the two will be used. Which one is undefined -XX:MaxPermSize with or without -XX:PermSize How do I write a correct micro-benchmark in Java? Real differences between "java -server" and "java -client"?