4

希望这是一个简单而快速的问题。我最近在 Netbeans 中开发了一个 CPU 密集型 Java 应用程序。它使用每秒数万次的 A* 寻路来解决瓷砖匹配游戏。该应用程序已完成,并且运行得非常快(我一直在 netbeans 中进行测试)。我将其计时为每秒 700 次尝试(每次尝试可能是 20 次左右的寻路)。当我构建项目时,它会创建一个 jar,我可以在 netbeans 之外运行它。如果我使用命令行(Windows 7)并使用 java -jar theFile.jar,我会以每秒 1000 次尝试的速度计时。这是可以理解的,因为 IDE 可能使用了一些 cpu 电源并阻止它(我的应用程序是多核的,您可以设置数字。我通常使用 3/4,因此它不会使我的系统减慢太多)。现在,令人困惑的部分。显然我不 不希望用户每次想在 Windows 上运行此应用程序时都必须使用命令行。他们应该能够点击罐子。问题是,当我双击 jar 文件时,程序每秒运行 300 次尝试!

为什么这三种运行完全相同的程序的方式会在其他条件不变的情况下对性能产生如此巨大的影响?我的解决方法是创建一个脚本来通过命令行运行 .jar,还是你们知道这里发生了什么?非常感谢!

编辑:新信息

我使用以下命令创建了一个批处理文件: java -jar theFile.jar 执行此命令时,它的运行速度与我在控制台中运行它的速度相同(因此,1000 att/sec)

但是,我还用一个简单的 c++ 程序制作了一个可执行文件。该程序只有几行,并且是 System("java -jar theFile.jar"); 并返回 0;。令人难以置信的是,它以双击 jar 文件的速度运行,大约 300att/sec。多么奇怪!它很可能是不同的 IDE 参数,但我不确定如何检查默认系统参数,或者如何针对这个特定的 jar 修改它们。

4

1 回答 1

3

您可能会遇到 HotSpot VM的客户端和服务器版本之间的差异。从这篇文章

  • 在通常用于客户端应用程序的平台上,JDK 附带了一个称为 Java HotSpot™ Client VM(客户端 VM)的 VM 实现。客户端 VM 已针对减少启动时间和内存占用进行了调整。它可以在启动应用程序时使用 -client 命令行选项来调用。

  • 在所有平台上,JDK 都带有 Java 虚拟机的实现,称为 Java HotSpot Server VM(服务器 VM)。服务器 VM 旨在实现最大的程序执行速度。它可以在启动应用程序时使用 -server 命令行选项来调用。

我猜测单击jar文件可能会调用客户端 VM,除非您设置了-server标志。本文提供了更多详细信息:

-client 和 -server 系统有什么区别?

这两个系统是不同的二进制文件。它们本质上是两个不同的编译器 (JIT),它们连接到同一个运行时系统。客户端系统最适合需要快速启动时间或占用空间小的应用程序,服务器系统最适合整体性能最重要的应用程序。一般来说,客户端系统更适合交互式应用程序,例如 GUI。其他一些差异包括编译策略、堆默认值和内联策略。

我从哪里获得服务器和客户端系统?

客户端和服务器系统都通过 32 位 Solaris 和 Linux 下载来下载。对于 32 位 Windows,如果您下载 JRE,您只能获得客户端,您需要下载 SDK 才能获得这两个系统。

对于 64 位,仅包括服务器系统。在 Solaris 上,64 位 JRE 是 32 位发行版之上的覆盖。但是,在 Linux 和 Windows 上,它是一个完全独立的发行版。

我希望java默认为-server。我有很多无法更改(或不想更改)的脚本。有没有办法做到这一点?

从 Java SE 5.0 开始,除了 32 位 Windows 之外,服务器 VM 将在服务器级机器上自动选择。服务器级机器的定义可能因版本而异,因此请查看相应的人体工程学文档以了解您的版本的定义。对于 5.0,它是 5.0 Java[tm] 虚拟机中的人体工程学。

我应该先预热循环以便 Hotspot 编译它们吗?

不需要为 HotSpot 预热循环。HotSpot 包含堆栈替换技术,该技术将编译一个正在运行(解释)的方法,并在它仍在循环中运行时替换它。无需浪费您的应用程序时间来预热看似无限(或非常长时间运行)的循环以获得更好的应用程序性能。

于 2013-02-28T03:15:31.067 回答