tags:

views:

139

answers:

6

Hello guys,

I think everyone is aware of -server command line JVM parameter. Does it make any sense while running Java application as Server??

I read that it does some more optimizations, and because of that, some of your Java code can behave differently like

boolean flag=true;
while(flag) { 
   if(checkMethod()) {
      flag=false;
   }
} 

[EDIT] this code will work fine(same) in both scenario 1. without -server and 2. with -server, Will update once again with proper testable code.

it will never come out of while loop..

We have just started a new project, should we start using -server for testing?
Are you using it?

& I wonder if it really make sense and it is really important, why official document/tutorials of server products like tomcat/jetty/geronimo etc. never use/show -server tag in code examples ????

Cheers

+5  A: 

That can't be right. Java will never execute code incorrectly no matter what switches you add. It can optimize out the checkMethod call only if it can be proven to always return the same value.

In general, the -server switch does help performance by optimizing more aggressively (it assumes that the routines will live longer and be called more often). They used to have columns for Java and Java -server in the Computer Language Shootout, but they seem to have removed the straight "Java" because it never beat Java -server.

I seem to remember the -server causing a somewhat significant increase in many benchmarks.

Bill K
i am sure, some reproduceable code is available.. current code is working same in both case. I'll edit it once I find it... It has threading also.. let me test manually once..
Nachiket
>> they seem to have removed the straight "Java" because it never beat Java -server << No, on the current Q6600 test machine the default without the -server switch would be -server. The -server is only used to make that obvious. With the shorter runtimes on the out-of-date Pentium 4 sometimes -client was a tiny bit faster http://shootout.alioth.debian.org/gp4/compare.php?lang=javaclient
igouy
+3  A: 

Your code listing is dangerous because it is not threadsafe, not because of the VM used. It is dangerous on all VMs. But to your question: the server VM is more aggressive in JITing your code so it tends to run faster at the expense of slower application startup. Note that the server VM is the default on some hardware configurations for some versions of java (e.g. for java 5, the -server flag is implied if the host has 2 or more GB of memory and 2 or more cores).

mpm
@mpm The code is thread-safe because "flag" is confined to the stack of the executing thread.
Steve Emmerson
Yeah, Steve is right. I should have looked at the code more closely, I just assumed it was the classic example of this problem, which can be found in many places. For example, http://mailinator.blogspot.com/2009/06/on-java-visibility.html
mpm
A: 

The -server flag does not change execution semantics. In your example, a JVM which would prevent loop exit would be simply incorrect, as in "does not comply to the Java specification", and also as in "plain wrong" too.

What optimization in general, and '-server' in particular, can do is change rules for the unspecified. Java is quite tightly specified, but it has a few fuzzy places, in particular with regards to floating point, and to unsynchronized concurrent accesses to memory.

For instance, with code like this:

int x = 0, y = 0;
void set(int x, int y)
{
    this.x = x;
    this.y = y;
}
int getX()
{
    return x;
}
int getY()
{
    return y;
}

and assuming that some code in a thread calls set(1, 1), and another calls getY() then getX(), then, without synchronization, the getY() could return 1 (the new value) and the getX() could return 0 (the old value): the first thread sets x then y at the source level, but from the point of view of the other thread, the write to y could happen before the write to x.

Code relying on update order from another thread without explicit synchronization (with 'synchronized' or 'volatile') is flawed, but may escape detection with tests. The -server flag makes the JVM more trigger-happy on such reordering, and thus may exhibit the bug. But the -server flag is not faulty here: the code is.

This means that using -server for testing is actually a good idea: it may help uncovering some bugs. For bug-free code, the -server flag is safe.

Thomas Pornin
+1  A: 

The -server option simply adjusts the just-in-time compiler to make different trade-offs. The server JIT will run heavier optimizations on code earlier, which makes start up slower, but is well suited for long lived processes. The client JIT tries to reduce start up time and does its optimizations over time. See the Java HotSpot documentation for more information

The overall effect is pretty minor, and it's one of many settings you might adjust when tuning an application.

The optimizations should never change the behavior of your program like in your example.

ataylor
+2  A: 

yes java can behave different when you use the -server flag, but that requires the program itself to have at least one error. The only case I can think of is a missing volatile or missing synchronisation for a variable accessed by multiple Threads.

class Runner extends Thread
{
boolean stop = false;
public void run()
{
   while (!stop)
   {
       doSomething();
   }
}
public void exit()
{
    stop = true;
}
}

Calling the exit() method without optimization will lead the thread to exit the loop, when optimization is turned on the optimizer may gues that the loop will never end and replace the test with a simple jump, as stop is not volatile and is not modified from within the loop.
This behavior has to be expected as a variable accessed by several threads should either be declared volatile or accessed only over synchronized methods.
just remembered that there is a stop() method in Thread, replaced it with exit() for clarity.

josefx
+1  A: 

It is possible for incorrect code (not thread safe) to appear to work correctly without -server, but to fail with it.

This is because optimizations that are applied sooner under -server might expose the bad code. In any case such code should be corrected.

Darron