短时间运行的 Java CLI 应用程序的性能

eps*_*lon 2 java performance jvm

我正在构建一个 java CLI 实用程序应用程序来处理文件中的一些数据。

除了从文件中读取之外,所有操作都是在内存中完成的。内存处理部分花费了令人惊讶的长时间,因此我尝试对其进行分析,但无法查明任何执行特别糟糕的特定函数。

我担心 JIT 无法在单次运行期间优化程序,因此我使用所有程序逻辑(包括读取输入文件)对函数的连续执行之间的运行时变化进行了基准测试,果然,运行时内存处理部分在多次执行后会出现故障,并且在第 5 次运行时已经缩小了近 10 倍。

我尝试在每次执行之前对输入数据进行混洗,但对此没有任何明显的影响。我不确定某些缓存是否可能导致这种改进或程序运行期间完成的 JIT 优化,但由于通常程序一次运行一次,因此它总是显示最差的性能。

是否有可能在第一次运行中获得良好的性能?有没有一种通用的方法来优化短时间运行的 java 应用程序的性能?

Ste*_*n C 6

您可能无法通过更改应用程序1, 2来优化启动时间和性能。特别是对于小型应用程序3。我当然不认为有“通用”的方法可以做到这一点;即适用于所有情况的优化。

然而,有一些 JVM 功能可以提高短命 JVM 的性能。

类数据共享 (CDS) 是一项功能,允许将 JIT 编译的类缓存在文件系统中(作为 CDS 存档),然后由以后运行的应用程序重用。此功能自 Java 5 起就可用(尽管在早期 Java 版本中存在限制)。

The CDS feature is controlled using the -Xshare JVM option.

  • -Xshare:dump generates a CDS archive during the run
  • -Xshare:off -Xshare:on and -Xshare:auto control whether an existing CDS archive will be used.

The other way to improve startup times for a HotSpot JVM is (was) to use Ahead Of Time (AOT) compilation. Basically, you compile your application to a native code binary using the jaotc command, and then run the executable it produces rather than the java command. The jaotc command is experimental and was introduced in Java 9.

It appears that jaotc was not included in the Java 16 builds published by Oracle, and is scheduled for removal in Java 17. (See JEP 410: Remove the Experimental AOT and JIT Compiler).

The current recommended way to get AOT compilation for Java is to use the GraalVM AOT Java compiler.


1 - You could convert into a client-server application where the server "up" all of the time. However, that has other problems, and doesn't eliminate the startup time issue for the client ... assuming that is coded in Java.
2 - According to @apangin, there are some other application tweaks that may could make you code more JIT friendly, though it will depend on what you code is currently doing.
3 - It is conceivable that the startup time for a large (long running) monolithic application could be improved by refactoring it so that subsystems of the application can be loaded and initialized only when they are needed. However, it doesn't sound like this would work for your use-case.

  • *“您可能无法通过更改应用程序来优化启动时间和性能”* - 这几乎*总是*可能的,特别是当您知道 JIT 代码性能更好时。有一些技术可以编写 JIT 友好的代码,但它们高度依赖于应用程序;如果没有看到实际的代码,很难给出建议。例如,应用程序启动缓慢的一个典型原因是[静态初始化程序中的计算](https://pangin.pro/posts/computation-in-static-initializer)。 (2认同)