通过将自己的应用程序类添加到 classes.jsa 来加快应用程序启动速度

2022-09-01 07:49:35

为了加快 JVM 的启动时间,Sun 开发人员决定在安装 JVM 期间预编译平台的标准运行时类是一个好主意。这些预编译的类可以在例如以下位置找到:

$JAVA_HOME\jre\bin\client\classes.jsa

我的公司目前正在开发一个Java独立应用程序,它带来了自己的JRE,所以通过将我们自己的应用程序类添加到这个jsa文件中来加快我们的应用程序启动时间将是一个绝佳的选择。

我不相信JSA文件是由魔术创建的,所以:它是如何创建的?我该如何欺骗 JVM 来合并我自己的类?

编辑:我已经发现了以下内容:

classes.jsa 由以下命令创建

java -Xshare:dump

要合并到转储中的类的列表可在 中找到。$JAVA_HOME/jre/lib/classlist

我甚至设法在这里添加了我自己的类(并将它们添加到rt.jar以便java找到它们),并在classlist文件下面生成我自己的校验和。

最后一个问题是:似乎只有java,com.sun和org.w3c包中的类才能被识别,如果我在原始包中保留相同的类,它们就不会被加载。我搜索了整个OpenJDK源代码以查找有关此内容的指针,但它似乎与保护域有关。如果有人对这个话题足够感兴趣并且有足够的知识,请添加一些指针供我进一步调查。


答案 1

从Java 8u40(和嵌入式Java 8u51)开始,Java现在支持应用程序类数据共享(AppCDS)(即共享存档中您自己的类)。在我们的嵌入式java上,我们发现启动改进>40%!非常棒,因为我们几乎没有工作...

https://blogs.oracle.com/thejavatutorials/entry/jdk_8u40_released


答案 2

你差不多就在那里,你只需要几个步骤就可以了。要将您自己的类添加到客户端.js您需要执行以下步骤:

  1. 类的限定名称(您有它)

  2. 这些类的类路径(你有它)

  3. 了解如何重新计算校验和(您拥有它)

  4. 转储新文件,提供您现在使用 Java 类预编译的类的类的类路径。

  5. 运行该程序,提供用于转储新类的相同类路径。jsa

若要提供要添加到类列表中的类所在的类路径,请使用该命令。当 JVM 搜索引导类所在的位置时,它将追加目录/JAR。classes.jsa 的默认空间非常小,如果需要改进它,可以使用 and 命令。您的转储命令类似于以下内容:-Xbootclasspath/a-XX:SharedReadWriteSize-XX:SharedReadOnlySize

java -Xshare:dump -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

最后一步是正常运行java应用程序,重新打开共享模式。您还需要在转储上添加时添加 excatly。它看起来像这样:Xbootclasspath

java myapp.java -Xshare:on -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

现在,您放在类列表上的每个类都与在同一 JVM 中运行的其他实例共享。


推荐