“java -server”和“java -client”之间有什么实际的区别吗?

我在孙的网站上只能找到一个模糊的

-服务器启动较慢,但应该运行得更快。

真正的区别是什么?(目前使用JDK 1.6.0_07。)


当前回答

我刚刚注意到的一个不同之处在于,在“客户端”模式下,JVM似乎会将一些未使用的内存归还给操作系统,而在“服务器”模式下,一旦JVM获取了内存,它就不会将其归还。这就是它在Solaris和Java6上的显示方式(使用prstat -Z查看分配给进程的内存数量)。

其他回答

我没有注意到两者在启动时间上有任何不同,但使用“-server”(Solaris服务器,每个人都使用SunRays来运行应用程序)时,应用程序性能的提高非常小。低于1.5。

IIRC,它涉及到垃圾收集策略。其理论是客户机和服务器在短寿命对象方面是不同的,这对现代GC算法很重要。

下面是服务器模式的链接。唉,他们没有提到客户端模式。

这里有一个关于GC的非常全面的链接;这是一篇比较基础的文章。不确定地址-服务器和-客户端,但这是相关的材料。

在No Fluff Just Stuff, Ken Sipe和Glenn Vandenburg都在这方面做了很棒的演讲。

client和server系统是不同的二进制文件。它们本质上是连接到同一个运行时系统的两个不同的编译器(jit)。客户端系统最适合需要快速启动时间或占用空间小的应用程序,服务器系统最适合对整体性能最重要的应用程序。一般来说,客户端系统更适合交互式应用程序,如gui

我们在两个开关上运行以下代码:

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--) {
        }
    }
}

注意:代码只编译过一次!这两个运行中的类是相同的!

客户端: java.exe -client -classpath C:\mywork\classes com.blogspot. sdoulder . looptest 花费时间:766

-服务器: java.exe -server -classpath C:\mywork\classes com.blogspot. sdoulder . looptest 时间:0

似乎更积极的优化服务器系统,删除循环,因为它知道它不执行任何操作!

参考

在旧版本的Java中,最明显的直接区别是分配给-client的内存,而不是分配给-server应用程序的内存。例如,在我的Linux系统上,我得到:

$ 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"

因为它默认为-server,但是使用-client选项我得到:

$ 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"

因此,使用-server,这个Java版本的大部分内存限制和初始分配都要高得多。

但是,这些值可以根据架构、操作系统和jvm版本的不同组合而改变。jvm的最新版本已经删除了标志,并删除了服务器和客户端之间的许多区别。

还要记住,您可以使用jvisualvm查看正在运行的jvm的所有细节。如果您的用户或模块设置JAVA_OPTS或使用脚本更改命令行选项,那么这很有用。这也可以让你实时监控堆和永久空间的使用情况以及许多其他统计数据。

当从1.4版本迁移到1.7版本(“1.7.0_55”)时。我们在这里观察到的是,在客户端和服务器模式下,分配给heapsize|permsize|ThreadStackSize参数的默认值没有这种差异。

顺便说一下,(http://www.oracle.com/technetwork/java/ergo5-140223.html)。这是从上面的链接中截取的片段。

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

1.7版本的ThreadStackSize更高,而在开放JDK论坛上,有讨论指出1.7版本的帧大小略高。 人们相信,在运行时可以根据应用程序的行为来度量真正的差异