java -server标志有什么意义吗?

时间:2010-01-22 19:06:35

标签: java jvm

我想每个人都知道-server命令行JVM参数。将Java应用程序作为Server运行时是否有意义?

我读到它做了一些更优化,因此,你的一些Java代码可能表现得不同,如

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

[编辑] 这个代码在两个方案1中都可以正常工作(相同),不使用-server和2.使用-server,将使用适当的可测试代码再次更新。

它永远不会出现在while循环中..

我们刚开始一个新项目,我们应该开始使用-server进行测试吗? 你在用它吗?

&安培;我想知道它是否真的有意义并且非常重要,为什么服务器产品的官方文档/教程如tomcat / jetty / geronimo等在代码示例中从不使用/ show -server标签????

干杯

6 个答案:

答案 0 :(得分:7)

这不可能是正确的。无论您添加什么开关,Java都不会错误地执行代码。只有在可以证明始终返回相同的值时,它才能优化checkMethod调用。

通常,-server开关通过更积极地进行优化来帮助提高性能(它假定例程将更长寿并且更频繁地调用)。他们曾经在计算机语言大战中使用了Java和Java -server的列,但他们似乎已经删除了直接的“Java”,因为它从未打败过Java -server。

我似乎记得-server导致了许多基准测试的显着增加。

答案 1 :(得分:4)

是的,当您使用-server标志时,java的行为会有所不同,但这需要程序本身至少有一个错误。我能想到的唯一情况是多个线程访问的变量缺少易失性或缺少同步。

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

调用exit()方法而不进行优化会导致线程退出循环,当启用优化时,优化器可能会认为循环永远不会结束并用简单的跳转替换测试,因为stop不是volatile并且不在循环内修改。
由于多个线程访问的变量应声明为volatile或仅通过同步方法访问,因此必须预期此行为 记得在Thread中有一个stop()方法,为了清楚起见,用exit()替换它。

答案 2 :(得分:2)

您的代码清单很危险,因为它不是线程安全的,不是因为使用了VM。这对所有虚拟机都很危险。但是对于你的问题:服务器VM在JITing代码方面更积极,所以它往往以更慢的应用程序启动为代价运行得更快。请注意,对于某些版本的Java,服务器VM是某些硬件配置的缺省值(例如,对于java 5,如果主机具有2 GB或更多GB内存以及2个或更多内核,则隐含-server标志。)

答案 3 :(得分:1)

-server选项只是调整即时编译器以进行不同的权衡。服务器JIT将在之前的代码上运行更严格的优化,这使得启动速度变慢,但非常适合长期存在的进程。客户端JIT尝试减少启动时间并随着时间的推移进行优化。有关详细信息,请参阅Java HotSpot documentation

整体效果非常小,这是调整应用程序时可能调整的众多设置之一。

优化不应该像您的示例中那样改变程序的行为。

答案 4 :(得分:1)

如果不使用-server,错误的代码(非线程安全)可能会正常工作,但是会失败。

这是因为在-server下更快应用的优化可能会暴露坏代码。   在任何情况下都应纠正此类代码。

答案 5 :(得分:0)

-server标志不会改变执行语义。在您的示例中,一个阻止循环退出的JVM将完全不正确,如“不符合Java规范”,以及“完全错误”也是如此。

一般来说,一般的优化,特别是'-server'可以做的是更改未指定的规则。 Java被严格指定,但它有一些模糊的地方,特别是关于浮点,以及对内存的不同步并发访问。

例如,使用以下代码:

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;
}

并假设线程中的某些代码调用set(1,1),另一个调用getY()然后调用getX(),然后,在没有同步的情况下,getY()可以返回1(新值)和getX ()可以返回0(旧值):第一个线程在源级别设置x然后是y,但是从另一个线程的角度来看,写入y可能在写入x之前发生。

依赖于来自另一个线程而没有显式同步的更新顺序的代码(带有'synchronized'或'volatile')是有缺陷的,但可能会通过测试逃避检测。 -server标志使JVM在这种重新排序时更加触发,因此可能会出现错误。但是-server标志在这里没有错误:代码是。

这意味着使用-server进行测试实际上是一个好主意:它可能有助于发现一些错误。对于无错误的代码,-server标志是安全的。