为什么JVM启动Java 12的启动速度更快

Mik*_*kov 1 java performance jvm java-12

这是一个细微但值得注意的区别:

$ for j in {5..12}; do . chjdk $j; time (java -version; for i in {1..1000}; do java x >/dev/null; done); echo ""; done
java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)

real    2m4.988s
user    0m59.832s
sys 0m18.856s

java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)

real    0m28.055s
user    0m24.012s
sys 0m4.216s

java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

real    0m31.225s
user    0m24.836s
sys 0m3.564s

java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

real    0m43.463s
user    0m35.948s
sys 0m6.516s

java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

real    1m29.909s
user    1m37.892s
sys 0m12.972s

java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

real    1m21.161s
user    1m24.412s
sys 0m13.044s

openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

real    0m56.932s
user    1m8.892s
sys 0m9.516s

openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)

real    0m39.930s
user    0m38.876s
sys 0m9.520s
Run Code Online (Sandbox Code Playgroud)

作为Java 12发行版的一部分,是否有特定更改?或者是测量错误?


更新资料

实际上,JVM的启动速度更快。感谢LppEddHolger提供的参考。

JEP 341-默认CDS存档

启动Java应用程序时,正在加载数千个类,这似乎使JVM减慢了启动速度。

类数据共享是一项功能,从JDK 8 Update 40开始就作为一项商业功能引入。它允许您将所有启动类打包到特定格式的存档中,此后应用程序的启动时间增加了。不久之后,引入了JEP 310:应用程序类-数据共享,这使我们不仅可以对系统类也可以对应用程序类进行相同的操作。

对于JDK类,它看起来像这样。首先,我们使用来转储类java -Xshare:dump,然后启动应用程序,告诉它使用以下缓存:java -Xshare:on -jar app.jar。而且启动速度有所提高。

但是-Xshare: dump,如果在创建JDK发行版的阶段执行该命令的默认结果是可以预料的,则每次编写似乎都很奇怪。根据文档,如果Java 8发行版是使用安装程序安装的,那么在安装时,它应该为您运行必要的命令。但为什么?发行套件不是以安装程序的形式而是以zip归档文件的形式发行,该怎么办?

由于JDK 12 CDS归档文件将由分发的创建者在链接后立即生成。即使是夜间构建(假设它们是64位的并且是本机的,也不用于交叉编译)。

从JDK 11开始,-Xshare: auto默认情况下已启用,并且这样的存档将被自动提取。因此,只需将其更新到JDK 12即可加快应用程序的启动速度!

Lpp*_*Edd 10

这可能与JEP 341-默认的CDS存档有关,这是JDK 12的新功能。

结束语
增强了JDK的构建过程,以使用默认的类列表在64位平台上生成类数据共享(CDS)存档。

目标
缩短开箱即用的启动时间
...

据我了解,即使在以前的发行版中,也可以通过使用-Xshare:dump/ -Xshare:on参数来实现相同的行为。该JEP使其成为默认值。


感谢Holger提供有关类数据共享的Oracle文章。

  • 是的,对该功能的处理非常奇怪。关于[一篇文章](https://docs.oracle.com/javase/6/docs/technotes/guides/vm/class-data-sharing.html),它说仅该功能受支持。客户端JVM,这意味着在安装过程中未为服务器JVM生成CDS,但是在此之后手动生成它确实可行。我认为,最初的计划是为Java 9开发一个优化的模块存储,以取代CDS。当它没有进入发行版时,就被忘记了重新关注CDS。 (3认同)
  • 这可能是主要原因,因为OP的数字显示JDK 8几乎与标准(在大多数环境中默认情况下创建CDS)相同。更高的版本在安装过程中发生了重大变化(因为删除了一些旧功能),包括新选项,即仅下载和解压缩zip归档文件,而没有实际的安装过程会生成CDS归档文件。 (2认同)
  • 请注意,存在适用于Java 8的[本文的更新版本](https://docs.oracle.com/javase/8/docs/technotes/guides/vm/class-data-sharing.html)。 (2认同)
  • Claes Redestad在此主题上有一个不错的博客:[预览:OpenJDK 12启动](https://cl4es.github.io/2018/12/28/Preview-OpenJDK-12-Startup.html) (2认同)