为什么JVM在启动Java12时启动得更快

为什么JVM在启动Java12时启动得更快,java,performance,jvm,java-12,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-

这是一个轻微但明显的区别:

$ 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
作为Java12版本的一部分,有什么特别改变了吗?还是这是一个测量错误


更新 事实上,JVM启动得更快。感谢LppEddHolger作为参考

当您启动Java应用程序时,会加载数千个类,这看起来像是JVM减慢了启动速度

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

对于JDK类,它看起来是这样的。首先我们用
java-Xshare:dump
转储类,然后启动应用程序,告诉它使用这个缓存:
java-Xshare:on-jar app.jar
。启动速度也有了一些提高

但是每次编写
-Xshare:dump
似乎很奇怪,如果在创建JDK发行版的阶段执行此命令的默认结果有点可预测的话。根据文档,如果Java8发行版是使用安装程序安装的,那么在安装时它应该为您运行必要的命令。但是为什么呢?分发工具包不是以安装程序的形式分发的,而是以zip存档的形式分发的,该如何处理

由于JDK 12 CD存档将由发行版的创建者在链接后立即生成。即使是夜间构建(假设它们是64位且本机的,而不是交叉编译)

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

这可能与-default-CDS归档有关,这是JDK 12的新功能

摘要
增强JDK构建过程以生成类数据共享 (CD)在64位平台上使用默认类列表进行归档

目标
提高开箱即用的启动时间

据我所知,通过使用
-Xshare:dump
/
-Xshare:on
参数,即使在以前的版本中也可以实现相同的行为。 这个JEP只是让它成为默认值


多亏了Holger在Oracle上的文章。

这可能与-default CD归档有关,这是JDK 12的新功能

摘要
增强JDK构建过程以生成类数据共享 (CD)在64位平台上使用默认类列表进行归档

目标
提高开箱即用的启动时间

据我所知,通过使用
-Xshare:dump
/
-Xshare:on
参数,即使在以前的版本中也可以实现相同的行为。 这个JEP只是让它成为默认值



感谢Holger在Oracle上发表的文章。

我们不知道这是否是测量错误;只有你能回答这个问题。启动时间随着版本的变化而上下波动;我不知道为什么这是一个问题。我知道他们最近试图更具体地解决这个问题,所以我想他们是想把它恢复到1.6-1.8时代的水平;每个最新版本中都有几个。这些可以加起来!我们不知道这是否是测量误差;只有你能回答这个问题。启动时间随着版本的变化而上下波动;我不知道为什么这是一个问题。我知道他们最近试图更具体地解决这个问题,所以我想他们是想把它恢复到1.6-1.8时代的水平;每个最新版本中都有几个。这些可以加起来!这可能是主要原因,因为OP的数据显示JDK 8几乎是标准的(在大多数环境中,CDS是默认创建的)。后来的版本在安装过程中有了重大的变化(因为删除了一些旧功能),包括只下载和提取zip存档的新选项,而不需要实际的安装过程来生成CD存档。@Holger感谢您的澄清。老实说,几乎所有与我讨论过这个问题的开发人员都不知道存在这样的优化。看起来它在市场上不是很受欢迎(或者只是被认为是理所当然的)。是的,这个功能的处理方式非常奇怪。关于这一点,它说该功能只支持客户端JVM,这意味着在安装过程中不会为服务器JVM生成CDS,但是,在安装之后手动生成CDS是可行的。我认为,最初的计划是为Java9开发一个优化的模块存储,以取代CD;当它没有进入发布版时,它就被遗忘了重新聚焦在CDS上。注意到有java 8。Claes Redestad在这个主题上有一个好的博客:这可能是主要原因,因为OP的数字显示JDK 8几乎是在PAR(大多数环境下默认是CDS)。后来的版本在安装过程中有了重大的变化(因为删除了一些旧功能),包括只下载和提取zip存档的新选项,而不需要实际的安装过程来生成CD存档。@Holger感谢您的澄清。老实说,几乎所有与我讨论过这个问题的开发人员都不知道存在这样的优化。看起来它在市场上不是很受欢迎(或者只是被认为是理所当然的)。是的,这个功能的处理方式非常奇怪。那儿