如何使用Class-java10的数据共享功能?

How to use Application Class-Data Sharing feature of java 10?

我在 Oracle 文档中了解了 CDS https://docs.oracle.com/javase/8/docs/technotes/guides/vm/class-data-sharing.html

我的理解是加载 jvm 所需的系统 class 文件被解析、验证,然后存储在 jre/lib/[arch]/client/classes.jsa 的存档中。而且他们还为jvm提供了他们的内存映射,所以jvm直接根据archive中给出的映射信息来映射内存。因此,这减少了每次 jvm 实例启动时 class 加载的开销。如有不妥请指正

现在到了 java10,我怎样才能为我的应用程序代码实现这一点? 其次,完整的应用程序代码是否符合 CDS 的条件,或者是否有一些限制?

创建和使用带有应用程序 class-data 的存档有三个基本步骤(有关更多详细信息,请阅读 my post about application class-data sharing):

  1. 正在创建要包含在存档中的 classes 列表:

    java -XX:+UseAppCDS
        -XX:DumpLoadedClassList=classes.lst
        -jar app.jar
    
  2. 正在创建存档:

    java -XX:+UseAppCDS -Xshare:dump 
        -XX:SharedClassListFile=classes.lst
        -XX:SharedArchiveFile=app-cds.jsa
        --class-path app.jar
    
  3. 使用存档:

    java -XX:+UseAppCDS -Xshare:on 
        -XX:SharedArchiveFile=app-cds.jsa
        -jar app.jar
    

请记住以下几点:

  • 创建存档时,class 路径不能使用通配符或展开的 JAR
  • 用于启动应用程序的 class 路径必须具有用于创建存档的路径作为前缀
  • 如果您有任何问题,请使用 -Xlog:class+load (more on -Xlog) 获取更多信息

AppCDS 的 JEP 示例展示了如何将您的应用程序 class 添加到共享存档。 至于限制,有几个:

  1. 直接 classes (.class) 存在于 class 路径上的目录中 无法添加到共享存档。看到这个 thread.
  2. 类 自定义加载 class 加载程序无法添加到共享存档。看到这个 thread.

使用 CDS/AppCDS 时还需要注意其他实际注意事项,例如:

  1. 如果更新文件系统上的 jar 文件,则必须重新创建共享存档。
  2. 如果您在 运行 时使用 Java 或 JVMTI 代理 modify/re-transform/redefine class 文件,则共享存档不会很有用,因为 classes 将从磁盘加载,因为代理需要实际的 class 文件数据,我认为这些数据未存储在共享存档中。

另一篇关于 CDS 和 AppCDS 的精彩而详细的文章是 https://simonis.github.io/cl4cds/

本文作者还编写了一个 tool 允许共享应用程序 classes,即使它们是由自定义 class 加载器加载的。

如果你有兴趣使用CDS,你也可以试试OpenJ9 JVM,这个功能已经存在很长时间了,而且更加成熟和完善。阅读更多相关信息 here