2010-01-22 55 views
1

我想每个人都知道-server命令行JVM参数。运行Java应用程序作为服务器时有意义吗?没有java -server标志有什么意义?

我读它做一些更多的优化,正因为如此,一些Java代码可以表现不同一样

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

请在[编辑]这个代码将正常工作(同)方案1.不带-server和带-server的服务器,将使用适当的可测试代码再次更新。

就再也回不来了,而循环..

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

&我不知道它是否真的有意义,它真的很重要,为什么tomcat/jetty/geronimo等服务器产品的官方文档/教程从未在代码示例中使用/显示服务器标签?

干杯

回答

4

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

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

调用不优化出口()方法会导致线程退出循环,当优化时,优化器可以客串环路将永远不会结束,并用简单的跳转替换试验,如停止不易变,并且不会在循环内修改。
此行为必须预期,因为由多个线程访问的变量应声明为volatile或仅通过同步方法访问。
只记得Thread中有一个stop()方法,为了清晰起见,用exit()取代了它。

7

这是不对的。不管你添加什么开关,Java都不会错误地执行代码。它只能在证明始终返回相同的值时才能优化checkMethod调用。

通常,-server开关通过更积极地进行优化(假定例程寿命更长,并且更频繁地调用)来确保性能。他们过去在Computer Language Shootout中有用于Java和Java-server的列,但他们似乎删除了直接的“Java”,因为它从未击败过Java-server。

我似乎记得-server导致许多基准测试中的某种程度的显着增加。

+0

我相信,一些可复制的代码是可用的..当前代码在这两种情况下工作相同。我会编辑它,一旦我找到它...它也有线程..也让我手动测试.. – Nachiket 2010-01-22 19:45:57

+0

>>他们似乎删除了直“Java”,因为它从来没有击败Java -server <<否,对目前的Q6600测试机默认没有-server开关就是-server。服务器仅用于使这一点变得明显。在过时的Pentium 4上运行时间较短 - 客户端稍微快一点http://shootout.alioth.debian.org/gp4/compare.php?lang=javaclient – igouy 2010-01-24 19:12:54

2

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

+1

@mpm代码是线程化的,因为“标志”被限制在正在执行的线程的堆栈中,所以是安全的。 – 2010-01-22 19:46:55

+1

是的,史蒂夫是对的。我应该更仔细地查看代码,我只是认为这是这个问题的典型例子,可以在很多地方找到。例如,http://mailinator.blogspot.com/2009/06/on-java-visibility.html – mpm 2010-01-22 19:53:15

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

并假设在一个线程调用一些代码设置为(1,1),而另一个呼叫的getY(),然后的getX(),则在不同步,getY()可以返回1(新值),getX()可以返回0(旧值):第一个线程设置x然后y在源级别,但是从另一个线程的角度来看,在写入x之前可能发生对y的写入。

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

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

1

-server选项简单地调整即时编译器以进行不同的权衡。服务器JIT将在较早的代码上运行较重的优化,这会使启动速度变慢,但非常适合长期存在的进程。客户JIT试图缩短启动时间并随着时间的推移进行优化。请参阅Java HotSpot documentation以获取更多信息

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

优化不应该像你的例子那样改变程序的行为。

1

不正确的代码(不是线程安全的)出现在没有服务器的情况下可以正常工作,但可能会失败。

这是因为在服务器下应用较早的优化可能会暴露错误的代码。 在任何情况下,这些代码都应该纠正。