JDK13的新特性:AppCDS详解

简介

AppCDS的全称是Application Class-Data Sharing。主要是用来在不同的JVM中共享Class-Data信息,从而提升应用程序的启动速度。

通常来说,如果要执行class字节码,JVM需要执行下面的一些步骤:给定一个类的名字,JVM需要从磁盘上面找到这个文件,加载,并验证字节码,最后将它加载进来。

如果JVM启动的时候需要加载成百上千个class,那么需要的就不是一个小数目了。

对于打包好的jar包来说,只要jar的内容不变,那么jar包中的类的数据始终是相同的。JVM在启动时候每次都会运行相同的加载步骤。

更多内容请访问www.flydean.com

AppCDS的作用就是将这些能够共享的数据归类成一个存储文件,在不同的JVM中共享。

基本步骤

对AppCDS有了基本的了解之后,我们讲一下AppCDS的大概工作流程:

  1. 选择要归档的class,并创建一个class的列表,用在归档中。( -XX:DumpLoadedClassList)

  2. 创建归档文件(-Xshare:dump和-XX:SharedArchiveFile)

  3. 使用归档文件(-Xshare:on 和 -XX:SharedArchiveFile)

新的JVM可以使用归档文件来启动,从而减少了class加载的步骤。同时加载到内存中的区域甚至可以在其他的JVM实例中共享。从而极大的提高了JVM的启动速度。

下面我们从JDK class文件归档和应用程序class文件归档两个方面来讲解AppCDS的具体使用。

JDK class文件归档

最简单的AppCDS的例子就是归档JDK的class文件。JDK12,JDK13默认情况下已经开启了AppCDS的支持。如果需要停用,我们可以添加 -Xshare:off。

下面的例子专门用于JDK10和JDK11。

创建JDK class-data archive

我们可以使用-Xshare:dump来创建JVM启动时候默认加载的Class-Data:

java -Xshare:dump -XX:SharedArchiveFile=/tmp/sharedarchive.jsa

上面我们添加了参数-XX:SharedArchiveFile,因为默认情况下java shared archive file文件会创建在JAVA_HOME/lib/server/下面,这个是需要root权限才能写入的。为了方便起见,我们手动指定了一个有读写权限的目录。

生成的文件大概有12M,接下来我们就可以使用这个JSA文件来启动java程序了。

使用JDK class-data archive启动应用程序

我们先写一个可以运行的CDS hello world:

public class CDSHelloWorld {
public static void main(String[] args) {
System.out.println("CDS Hello World");
}
}

编译之后,我们运行下面的命令来使用上面创建的jsa文件:

java -Xlog:class+load:file=/tmp/sharedarchive.log  -XX:SharedArchiveFile=/tmp/sharedarchive.jsa --enable-preview CDSHelloWorld

上面的命令添加了两个运行时参数:

-XX:SharedArchiveFile表示使用哪个具体的jsa文件来运行java程序。

-Xlog:class+load:file主要是做调试用的,将会把JVM的class load信息输出到指定的文件中,方便我们查看。这个unified logging特性是在JDK9中添加的,后面我们也会详细介绍。

简单查看一下生产的log文件:

[0.010s][info][class,load] opened: /Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home/lib/modules
[0.017s][info][class,load] java.lang.Object source: shared objects file
[0.017s][info][class,load] java.io.Serializable source: shared objects file
[0.017s][info][class,load] java.lang.Comparable source: shared objects file
...
[0.056s][info][class,load] CDSHelloWorld source: file:/Users/learn-java-base-9-to-14/java-13/target/classes/

从生成的日志文件我们可以看到,除了自己写的java文件,其他的java class都是从shared objects file中加载的。

运行时间对比

我们可以简单的使用time命令来对两种情况进行一下对比,看具体的运行时间差别:

 time  java -Xlog:class+load:file=/tmp/sharedarchive.log  -XX:SharedArchiveFile=/tmp/sharedarchive.jsa --enable-preview CDSHelloWorld
CDS Hello World
java -Xlog:class+load:file=/tmp/sharedarchive.log --enable-preview 0.06s user
0.06s system
77% cpu
0.164 total
time java  --enable-preview CDSHelloWorld
CDS Hello World
java --enable-preview CDSHelloWorld 0.09s user
0.06s system
66% cpu
0.222 total

HelloWorld只是一个简单的例子,可能两者的区别还不是特别明显。

如果是大型的项目,处理JDK自带的class之外,我们还可以将项目中共享的模块做成jsa文件,从而提升启动速度。

应用程序class文件归档

应用程序class文件归档和上面讲的JDK class文件归档很类似。基本步骤就是:1.列出运行应用程序时需要加载的class文件。2.将这class文件归档。

在JDK13之前,我们需要两步才能生成jsa文件。在JDK13之后,只需要一个命令就行了。

生成应用程序加载class的列表

我们可以使用XX:DumpLoadedClassList来生成应用程序加载class的列表:

java -XX:DumpLoadedClassList=/tmp/classes.lst --enable-preview CDSHelloWorld

我们可以得到类似下面的class文件列表:

java/lang/Object
java/io/Serializable
java/lang/Comparable
java/lang/CharSequence
java/lang/constant/Constable
java/lang/constant/ConstantDesc

使用class文件列表生成jsa文件

有了class文件列表,我们就可以生成jsa文件了:

java -Xshare:dump -XX:SharedArchiveFile=/tmp/sharedarchive.jsa -XX:SharedClassListFile=/tmp/classes.lst  --enable-preview CDSHelloWorld

跟之前的例子一样,只不过多了一个-XX:SharedClassListFile参数。

JDK13的新用法

在JDK13,一切都变得简单了,只需要一个-XX:ArchiveClassesAtExit就好:

java -XX:ArchiveClassesAtExit=/tmp/sharedarchive.jsa  --enable-preview CDSHelloWorld

JVM将会在退出时生成jsa文件。

总结

AppCDS是一个新特性,在特别关注java启动时间的情况下可以考虑使用。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jdk13-appcds/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

JDK13的新特性:AppCDS详解的更多相关文章

  1. JDK19新特性使用详解

    前提 JDK19于2022-09-20发布GA版本,本文将会详细介绍JDK19新特性的使用. 新特性列表 新特性列表如下: JPE-405:Record模式(预览功能) JPE-422:JDK移植到L ...

  2. HTML5新特性及详解

    什么是HTML5:HTML5 是下一代的HTML,将成为 HTML.XHTML 以及 HTML DOM 的新标准. 为 HTML5 建立的一些规则: 新特性应该基于 HTML.CSS.DOM 以及 J ...

  3. iOS7新特性-NSURLSession详解

    前言:本文由DevDiv版主@jas 原创翻译,转载请注明出处!原文:http://www.shinobicontrols.com/b ... day-1-nsurlsession/ 大家都知道,过去 ...

  4. Php5.5新特性 Generators详解

    在PHP5.5.0版本中,新增了生成器(Generators)特性,用于简化实现迭代器接口(Iterator)创建简单的迭代器的复杂性. 通过生成器,我们可以轻松的使用foreach迭代一系列的数据, ...

  5. Java8新特性--lamada详解

    最近玩了一下这个,感觉挺有趣的,语法使用起来很简洁,让代码看起来挺清爽易读的. 看了一下源码,发现挺充分的利用了jak1.5的特性(注解.泛型). 但是,具体的实现流程还是有点不通透,先Mark,等用 ...

  6. Servlet3.0新特性使用详解

    可插拔的Web框架 几乎所有基于Java的web框架都建立在servlet之上.现今大多数web框架要么通过servlet.要么通过Web.xml插入.利用标注(Annotation)来定义servl ...

  7. Java8新特性: CompletableFuture详解

    CompletableFuture实现了CompletionStage接口和Future接口,前者是对后者的一个扩展,增加了异步回调.流式处理.多个Future组合处理的能力,使Java在处理多任务的 ...

  8. ios新特征 ARC详解

    IOS ARC 分类: IOS ARC2013-01-17 09:16 2069人阅读 评论(0) 收藏 举报   目录(?)[+]   关闭工程的ARC(Automatic Reference Co ...

  9. ios中键值编码kvc和键值监听kvo的特性及详解

    总结: kvc键值编码  1.就是在oc中可以对属性进行动态读写(以往都是自己赋值属性)           2. 如果方法属性的关键字和需要数据中的关键字相同的话                  ...

  10. [转]Oracle 11g R2 RAC高可用连接特性 – SCAN详解

    原文地址:http://czmmiao.iteye.com/blog/2124373   昨天帮朋友解决11g RAC SCAN问题,当时为这朋友简单解答了一些SCAN特性相关的问题,但我知道这仅仅是 ...

随机推荐

  1. dart的map方法如何获取index

    一.前言 我们常常用dart中的map方法遍历List,但是直接用map,只能取到value,得不到index,这是因为map方法就只给了一个value,map的实现如下图: 下面就看看获取index ...

  2. CSRF(Steam的链接不用随便点)

    漏洞详解 CSRF 漏洞原理: 攻击者会冒充或利用用户本人对web服务器发送请求,然而web服务器无法识别该请求是否为用户本人所发送,因此造成各种危害. 漏洞利用过程: 1)首先需要用户登录了上网站, ...

  3. Linux 多进程服务配置 systemd

    目录 Linux 多进程服务配置 systemd sysvinit和systemd 多进程保活 创建配置文件(设定重试次数) 多进程服务管理 链式启动(服务依赖) 指定关闭进程方式 - ExecSto ...

  4. Java 求数值型数组中的最大元素 最小值 平均值 总和等 要求:随机数是 两位数

    1 /* 2 * 3 * 算法考查:求数值型数组中的最大元素 最小值 平均值 总和等 4 * 要求:随机数是 两位数 5 * [10,99] 6 * 公式:(int)(Math.random()*(9 ...

  5. Nfs 共享存储搭建

    Nfs 共享存储搭建 为了实现不同操作系统中的数据共享,我们一般会搭建一些用于文件共享的服务器,nfs服务器就是其中一种,它实现的是linux与linux之间的共享.今天我将把如何在linux系统搭建 ...

  6. ip 表单验证 vue iview

    ip 表单验证 vue iview template <Row v-show="config.bindIP"> <Col span="12"& ...

  7. npm install 的执行顺序,和 安装包的源死磕

    npm install 源的地址加载执行顺序 从近到远 lock文件 这里直接就记录了 包的下载地址 .npmrc 里面的内容 registry=http://registry.npm.xxxx.co ...

  8. 13 种在 JavaScript 中删除/过滤数组的方法【转】

    英文 | https://javascript.plainenglish.io/13-methods-to-remove-filter-an-item-in-an-array-and-array-of ...

  9. 学习笔记-涛讲F#(基础)

    目录 简介 类型推导 多个输入参数的函数 定义单位 偏函数 常量也是函数 返回值(unit与ignore) 函数串联实现"开方乘十" 使用管道符 |> 元组(参数加上括号) ...

  10. Windows App SDK? C++/WinRT? 狗都不学!

    空荡荡的官网开发文档,打开直接心凉一截! 只写个Hello World教程就敢宣布自己为"跨时代"新产品? 什么"C++桌面开发者的狂欢"?什么Project ...