“java -server”和“java -client”之间的真正区别?

2022-08-31 04:36:48

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

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

“-服务器启动速度较慢,但运行速度应更快”。

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


答案 1

这实际上与 HotSpot 和默认选项值Java HotSpot VM 选项)相关联,这些值在客户端和服务器配置之间有所不同。

摘自白皮书第 2 章Java HotSpot Performance Engine Architecture):

JDK 包括两种 VM 类型 - 客户端产品和针对服务器应用程序优化的 VM。这两种解决方案共享 Java HotSpot 运行时环境代码库,但使用不同的编译器,这些编译器适合客户端和服务器的独特性能特征。这些差异包括编译内联策略和堆默认值。

尽管服务器和客户端 VM 类似,但服务器 VM 已经过专门调整,以最大限度地提高峰值运行速度。它旨在执行长时间运行的服务器应用程序,这些应用程序需要尽可能快的运行速度,而不是快速启动时间或更小的运行时内存占用。

客户端 VM 编译器可作为经典 VM 和以前版本的 JDK 使用的实时 (JIT) 编译器的升级。客户端 VM 为应用程序和小程序提供了改进的运行时性能。Java HotSpot 客户端虚拟机经过专门调整,可减少应用程序启动时间和内存占用,使其特别适合客户端环境。通常,客户端系统更适合 GUI。

因此,真正的区别还在于编译器级别:

客户端 VM 编译器不会尝试执行编译器在服务器 VM 中执行的许多更复杂的优化,但作为交换,它花费更少的时间来分析和编译一段代码。这意味着客户端 VM 可以更快地启动,并且需要的内存占用量更小。

Server VM 包含一个高级自适应编译器,该编译器支持通过优化C++编译器执行的许多相同类型的优化,以及传统编译器无法完成的一些优化,例如跨虚拟方法调用的主动内联。与静态编译器相比,这是一个竞争优势和性能优势。自适应优化技术的方法非常灵活,通常甚至优于高级静态分析和编译技术。

注意:jdk6 update 10 的发布(参见更新发行说明:1.6.0_10 中的更改)试图缩短启动时间,但原因与热点选项不同,使用更小的内核进行打包。


G. Demecki在评论中指出,在64位版本的JDK中,该选项多年来一直被忽略。
请参阅 Windows java 命令-client

-client

选择 Java HotSpot Client VM。
支持 64 位的 JDK 当前忽略此选项,而是使用 Java 热点服务器 VM


2022年:Holger评论中引用了JavaSE6 / Server-Class Machine Detection,并添加了:

只有在32位Windows系统上,才被无条件地选择。
其他系统检查机器是否为“服务器类”,当具有至少2个内核和至少2GiB的内存时,该类就满足了。-client

这就解释了为什么几乎所有东西现在都使用了相当长的一段时间。即使是你能找到的最便宜的计算机,也是“服务器级”机器。Sun/Oracle 64版本甚至没有附带客户端JVM。-server


答案 2

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

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

因此,对于大多数内存限制和初始分配,此版本要高得多。-serverjava

但是,对于体系结构、操作系统和 jvm 版本的不同组合,这些值可能会更改。jvm的最新版本已经删除了标志,并重新移动了服务器和客户端之间的许多区别。

还要记住,您可以使用 查看运行的所有详细信息。如果您的用户或模块设置或使用更改命令行选项的脚本,这将非常有用。这还可以让您实时监控烫发空间使用情况以及许多其他统计信息。jvmjvisualvmJAVA_OPTS


推荐