“java -server”和“java -client”之间是否有任何实际的区别?
我在Sun的网站上找到的一切都是模糊的
“ - 服务器启动速度较慢但应该运行得更快”。
真正的区别是什么? (目前使用JDK 1.6.0_07。)
答案 0 :(得分:347)
这实际上与 HotSpot 和默认的选项值(Java HotSpot VM Options)相关联,这些值在客户端和服务器配置之间有所不同。
来自白皮书的Chapter 2(The Java HotSpot Performance Engine Architecture):
JDK包括两种VM:一种是客户端产品,另一种是针对服务器应用程序调整的VM。这两个解决方案共享Java HotSpot运行时环境代码库,但使用适合客户端和服务器的独特性能特征的不同编译器。这些差异包括编译内联策略和堆默认值。
虽然服务器和客户端虚拟机类似,但服务器虚拟机已经过专门调整,可以最大限度地提高峰值运行速度。它用于执行长时间运行的服务器应用程序,这些应用程序需要尽可能快的运行速度,而不是快速启动时间或更小的运行时内存占用。
客户端VM编译器用作旧版本JDK使用的Classic VM和实时(JIT)编译器的升级。客户端VM为应用程序和小程序提供了改进的运行时性能。 Java HotSpot客户端VM经过专门调整,可缩短应用程序启动时间和内存占用,使其特别适合客户端环境。通常,客户端系统更适合GUI。
所以真正的区别也在于编译器级别:
客户端VM编译器不会尝试执行服务器VM中编译器执行的许多更复杂的优化,但作为交换,它需要更少的时间来分析和编译一段代码。这意味着客户端VM可以更快地启动并且需要更小的内存占用。
服务器VM包含一个高级自适应编译器,它支持通过优化C ++编译器执行的许多相同类型的优化,以及传统编译器无法完成的一些优化,例如跨虚拟方法调用的积极内联。与静态编译器相比,这是一种竞争优势和性能优势。自适应优化技术的方法非常灵活,通常甚至优于高级静态分析和编译技术。
注意: jdk6 update 10 (请参阅Update Release Notes:Changes in 1.6.0_10)的发布试图改善启动时间,但由于与热点选项不同的原因,使用更小的内核进行不同的打包
G. Demecki指出in the comments在64位版本的JDK中,-client
选项会被忽略多年。
见Windows java
command:
-client
选择Java HotSpot客户端VM 64位功能的JDK当前忽略此选项,而是使用Java Hotspot Server VM 。
答案 1 :(得分:32)
我刚才注意到的一个区别是,在“客户端”模式下,似乎JVM实际上将一些未使用的内存返回给操作系统,而使用“服务器”模式,一旦JVM抓取内存,它就赢了“把它还给我。这就是它在Solaris上使用Java6的方式(使用prstat -Z
来查看分配给进程的内存量)。
答案 2 :(得分:28)
-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--) {
}
}
}
注意:代码只编译一次!两次运行中的类都相同!
使用-client:
java.exe -client -classpath C:\ mywork \ classes com.blogspot.sdoulger.LoopTest
花费的时间:766
使用-server:
java.exe -server -classpath C:\ mywork \ classes com.blogspot.sdoulger.LoopTest
花费的时间:0
似乎对服务器系统进行了更积极的优化,删除循环,因为它知道它不执行任何操作!
答案 3 :(得分:21)
Oracle的在线文档提供了Java SE 7的一些信息。
在Windows的java – the Java application launcher页面上,64位JDK中忽略-client
选项:
选择Java HotSpot Client VM。具有64位功能的jdk当前忽略此选项,而是使用Java HotSpot Server VM。
然而(为了让事情变得有趣),在-server
下说明:
选择Java HotSpot Server VM。在支持64位的jdk上,仅支持Java HotSpot Server VM,因此-server选项是隐式的。这可能会在将来的版本中发生变化。
Server-Class Machine Detection页面提供有关OS和架构选择的VM的信息。
我不知道这对JDK 6有多少。
答案 4 :(得分:15)
IIRC服务器VM在启动时执行更多热点优化,因此运行速度更快,但需要更长时间才能启动并使用更多内存。客户端VM推迟了大部分优化,以便更快地启动。
编辑添加:来自Sun的Here's some info,它不是非常具体,但会给你一些想法。
答案 5 :(得分:14)
来自Goetz - 实践中的Java并发:
- 调试提示:对于服务器应用程序,请务必在调用JVM时始终指定
醇>-server
JVM命令行开关,即使对于 开发和测试。服务器JVM执行更多优化 比客户端JVM,例如从循环中提取变量 没有在循环中修改;可能似乎在 开发环境(客户端JVM)可以在部署中中断 环境(服务器JVM)。例如,如果我们“忘记”宣布 清单3.4中的变量aslele as volatile,服务器JVM可以 将测试从环路中提升(将其转换为无限循环),但是 客户端JVM不会。出现的无限循环 开发成本远远低于仅出现的开发成本 生产。清单3.4。数羊。
volatile boolean asleep; ... while (!asleep) countSomeSheep();
我的重点。 YMMV
答案 6 :(得分:5)
Here is a link。唉,他们没有提到客户模式。
Here is a very thorough link一般关于GC;这是more basic article。不确定地址-server是否与-client相关,但这是相关材料。
在No Fluff Just Stuff,Ken Sipe和Glenn Vandenburg就这类事情进行了很好的讨论。
答案 7 :(得分:3)
我没有注意到2之间的启动时间有任何差异,但是使用“-server”(Solaris服务器,每个人都使用SunRays来运行应用程序),应用程序性能的改进非常小。那是在1.5以下。
答案 8 :(得分:1)
上次我看过这个,(并且不可否认它已经有一段时间了)我注意到的最大区别在于垃圾收集。
IIRC:
如果您可以使用jvisualvm工具比较两个Java VM,一个客户端,一个服务器,您应该看到垃圾收集的频率和效果的差异,以及代。
我有一对屏幕截图显示差异非常好,但我无法重现,因为我有一个只实现服务器VM的64位JVM。 (而且我也不会为在我的系统上下载和纠缠32位版本而烦恼。)
这似乎不再是这种情况,尝试在服务器和客户端虚拟机的Windows上运行一些代码,我似乎得到了两者的相同代模型...
答案 9 :(得分:1)
当从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
ThreadStackSize在1.7中更高,而在通过Open JDK论坛时,有讨论称1.7版本的帧大小稍高。 据信,根据您的应用程序行为,可以在运行时测量真正的差异