如何加快Java VM(JVM)的启动时间?

Hub*_*cki 37 java performance

我正在运行启动多个JVM进程的测试.与在JVM中运行的实际测试时间相比,JVM的摘要启动时间非常重要.我如何加快速度?

我已经使用了"-client"选项,这确实有所帮助,但没有我想要的那么多.有没有其他方法,比如预加载一堆JVM并以某种方式重用它们?

Pet*_*ham 35

如果你确实想重用JVM,那么"某种程度上"可能是Nailgun.Nailgun保持JVM运行,然后使用轻型本机客户端启动特定类并处理控制台io.这对于运行小命令行Java实用程序很有用,但是当它重用时,相同的JVM可以累积状态.

要以运行多个JVM为代价来解决状态累积问题,另一个选择是Drip.Drip通过正确的类路径和其他JVM选项保留了一个新的JVM保留,因此您可以在需要时快速连接并使用它,然后将其丢弃.Drip散列JVM选项并存储有关如何以散列值作为名称连接到目录中的JVM的信息.


Cla*_*tad 11

JVM启动性能可以通过多种方式得到改进:CDS,直接调整,CPU固定和jlink(自JDK 9以来)可以是很好的选择.AOT(JDK 9,仅限Linux)有一些粗略的边缘,但可以调整以帮助小型应用程序.

CDS

类数据共享是在1.5版本中为客户端VM开发的,但自从开始使用HotSpot的所有变体(自8年以来的所有GC)以来已经有了很大的改进,在启用时大大提高了启动性能.

CDS始终在32位JRE客户端安装上启用,但可能需要在其他地方启用一些手动步骤:

  1. 运行java -Xshare:dump以生成CDS共享存档
  2. 添加-Xshare:auto到您的命令以确保它已被使用

其他调整

虽然-client可能会或可能不会实际执行任何操作(许多系统上的JVM不附带客户端VM - 实际上从9开始都没有),有很多方法可以调整HotSpot服务器JVM以使其更像客户端VM:

  • 仅使用C1(客户端)编译器: -XX:TieredStopAtLevel=1
  • 使用尽可能少的编译器线程: -XX:CICompilerCount=1
  • 使用单线程串行GC: -XX:+UseSerialGC
  • 限制堆使用(特别是在大型系统上),例如, -Xmx512m

这应该足以为小型短期运行应用程序提升启动速度,但可能会对峰值性能产生非常不利的影响.您当然可以通过禁用可能未使用的功能来进一步实现,例如-XX:-UsePerfData(禁用使用MXBeans和jvmstat可检索的某些运行时信息).

高级

  • jlink是Java 9中提供的一种新工具,它允许您构建自定义运行时映像.如果您的控制台应用程序仅使用一小部分JDK模块,则可以使自定义运行时非常小,这可以进一步缩短启动时间.一个只包含java.base模块的最小图像,可能会将启动时间提高大约10-20ms,具体取决于硬件和其他调整:$JAVA_HOME/bin/jlink --add-modules java.base --module-path $JAVA_HOME/jmods --output jbase

  • (仅限Linux)Java 9引入了一个实验性AOT编译器,jaotc可用于帮助应用程序更快地启动,并且可以减少周期.开箱即用它可能会减慢立即启动速度(因为AOT代码是一个共享库,它增加了自己的I/O开销,不支持串行GC ..),但仔细调整我们'我们看到它将小型应用程序的启动时间缩短了15-30%.

  • CPU固定:在大型系统上,我们已经看到源自套接字之间的缓存一致性流量的效果,并且绑定到单个CPU节点可以大大缩短启动时间.在Linux上numactl --cpunodebind=0 $JAVA_HOME/bin/java ...应该做的事情.

总而言之,我们已经能够在短至35毫秒内完成最少的应用程序(JDK 9 GA).各种启动优化已进入JDK10分支,我现在看到数字低至28ms.

  • `jaotc` 已在 JDK 17 中删除。替代方案是 GraalVM 原生映像,尽管它也有一些问题。 (2认同)

Bri*_*new 2

为什么不在一个 JVM 中加载所有测试?你能做到以下一项或多项吗?

  1. 通过更高级别的类加载所有测试?
  2. 在列表(配置文件)中指定测试类并通过Class.forName()?按顺序加载每个测试类
  3. 如果隔离很重要,您可以为每个测试创建不同的类加载器

如果内存分配相当大,则可以通过将 JVM 内存启动大小指定为与最大可分配内存 ( -Xmsvs -Xmx) 相同的数字来加快速度,这将使 JVM 不必返回操作系统来获取更多内存。但在这种情况下,我认为这不太可能成为问题。