OpenJdk 初始启动时间很慢

run*_*len 5 java classloader classloading openjdk-11

我在服务器上运行 openjdk 11.0.3。每当服务器重新启动时(每晚):对于我的应用程序的第一次初始启动,用户必须等待 35 秒才能启动应用程序。(在从 main 方法编写第一个 System.out.println 之前。)(尽管后续启动非常快)我尝试了以下选项来调试它:

-Xlog:class+load:file=classload.txt
Run Code Online (Sandbox Code Playgroud)

以下是最重要的发现:

... 
[2.284s][info][class,load] jdk.internal.loader.URLClassPath$FileLoader source: jrt:/java.base
[5.032s][info][class,load] sun.security.rsa.RSASignature$SHA1withRSA source: jrt:/java.base
…
[5.051s][info][class,load] java.util.LinkedList$Node source: jrt:/java.base 
[8.121s][info][class,load] pos.LFChangeable source: file:/C:/Users/rho/AppData/Roaming/edapp/pos.jar
…
[8.135s][info][class,load] java.io.FileNotFoundException source: jrt:/java.base
[10.584s][info][class,load] sun.reflect.misc.ReflectUtil source: jrt:/java.base
…
[11.744s][info][class,load] java.security.NoSuchAlgorithmException source: jrt:/java.base
[34.853s][info][class,load] jdk.internal.logger.DefaultLoggerFinder source: jrt:/java.base
Run Code Online (Sandbox Code Playgroud)

为什么在加载 java.security.NoSuchAlgorithmException 和 jdk.internal.logger.DefaultLoggerFinder 之间挂起 23 秒?那么其他几秒钟的减速呢?

编辑:根据评论,我会澄清一些。这是一个 Windows rdp 服务器。实际上,它不止一台服务器,但问题仍然存在于所有服务器上。该应用程序是一个独立的应用程序。所以每天早上都会出现问题,因为登录启动应用程序的用户会在“没有任何反应”时尝试多次启动它。我现在已经多次尝试重新启动其中一台服务器,这就是我发现的:

重新启动后使用 java11 启动我的应用程序平均需要 40 秒,然后才会出现第一个 System.out.println。然后在我的第一个 JFrame 显示之前只有 1-2 秒。重新启动后使用 java8 (sun) 启动我的应用程序在第一个 System.out.println 之前平均需要 16 秒。但是在我的第一个 JFrame 显示之前,我得到了 25 秒的延迟。在已经使用 java8 启动之后使用 java11 启动我的应用程序平均需要 4-6 秒。

Hol*_*ger 5

您的应用程序可能会因缺少 \xe2\x80\x9cclass 数据共享 (CDS) 存档\xe2\x80\x9d 而受到影响。这样的存档可以更快地加载标准类,并且由以前版本的某些安装程序默认生成,但 OpenJDK\xc2\xa011 没有安装程序。

\n\n

JEP 341解决了这个问题:

\n\n
\n

目前,JDK 映像在目录中包含在构建时生成的默认类列表lib。想要利用 CDS 的用户,即使只使用 JDK 中提供的默认类列表,也必须执行java -Xshare:dump额外的步骤。此选项已记录在案,但许多用户不知道。

\n
\n\n

因此,虽然这个 JEP 是关于 JDK\xc2\xa012 自动执行必要的步骤,但它也提到了 JDK\xc2\xa011 的修复:只需java -Xshare:dump在命令行上运行一次,即可生成存档。

\n\n

请注意,您可以通过在 CDS 中包含应用程序类来进一步缩短启动时间。另请参阅JDK\xc2\xa011 文档的类数据共享部分。

\n