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

新手上路,请多包涵

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

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

“-server 启动速度较慢但应该运行得更快”。

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

原文由 Paul Tomblin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 771
2 个回答

这实际上与 HotSpot 和默认 _选项值_( Java HotSpot VM 选项)有关,客户端和服务器配置之间存在差异。

来自白皮书的 第 2 章Java HotSpot 性能引擎架构):

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

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

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

所以真正的区别还在于编译器级别:

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

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

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


G. Demecki 在评论 中指出,在 64 位版本的 JDK 中, -client 选项多年来一直被忽略。

请参阅 Windows java 命令

 -client

选择 Java HotSpot 客户端 VM。

目前支持 64 位的 JDK 会忽略此选项,而是使用 Java Hotspot Server VM


2022 年: Holger评论提到 JavaSE6 / Server-Class Machine Detection ,并添加:

只有在 32 位 Windows 系统上, -client 被无条件选中。

其他系统检查机器是否为“服务器类”,这在至少有 2 个内核和至少 2GiB 内存时满足。

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

原文由 VonC 发布,翻译遵循 CC BY-SA 4.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 或使用更改命令行选项的脚本,这将很有用。这还可以让您实时监控 permgen 空间使用情况以及许多其他统计信息。

原文由 Mark Booth 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题