Java SE 10 Application Class-Data Sharing 示例
Java SE 10 Application Class-Data Sharing 示例
作者:Grey
原文地址:Java SE 10 Application Class-Data Sharing 示例
Class-Data Sharing
CDS 全称 Class-Data Sharing。主要是用来在不同的 JVM 中共享 Class-Data 信息,从而提升应用程序的启动速度。
通常来说,如果要执行 class 字节码,JVM需要执行下面的一些步骤:给定一个类的名字,JVM 需要从磁盘上面找到这个文件,加载,并验证字节码,最后将它加载进来。如果 JVM 启动的时候需要加载成百上千个 class ,那么需要的就不是一个小数目了。
对于打包好的 jar 包来说,只要 jar 的内容不变,那么 jar 包中的类的数据始终是相同的。JVM 在启动时候每次都会运行相同的加载步骤。CDS 的作用就是将这些能够共享的数据归类成一个存储文件,在不同的 JVM 中共享。这样可以实现两个目标:
- 缩短JVM的启动时间。
- 减少JVM的内存占用。
当 JVM 启动时,它从文件系统中加载 JDK 类库(到JDK 8为止,从jre/lib/rt.jar
文件;从JDK 9开始,从jmods
目录下的jmod
文件)。在这个过程中,类文件被从档案中提取出来,转换为特定架构的二进制形式,并存储在JVM进程的主内存中。
如果在同一台机器上启动了多个JVM,这个过程会重复进行。每个 JVM 在内存中保留其类库的副本。
CDS 的工作原理如下。
- 使用
-Xshare:dump
命令,创建一个叫做classes.jsa
的文件(JSA 代表 Java Shared Archive)。这个文件包含了当前架构下的二进制格式的完整类库。 - 当 JVM 启动时,操作系统使用 内存映射 I/O将该文件 "映射 "到 JVM 的内存中。首先,这比加载 jar 或 jmod 文件要快。其次,操作系统只将文件加载到 RAM 中一次,为每个 JVM 进程提供同一内存区域的只读视图。
Application Class-Data Sharing
Application Class-Data Sharing 扩展了 CDS,不仅可以将 JDK 类库,还可以将应用程序的类存储在 JSA 文件中,并在 JVM 进程中共享。
以下示例代码演示了App CDS 的功能。
规划项目目录
hello-cds
- src
- git
- snippets
- cds
- App.java
- Helper.java
Java 版本需要使用 JDK 10。
代码清单
App.java
package git.snippets.cds;
public class App {
public static void main(String[] args) {
new Helper().greet();
}
}
Helper.java
package git.snippets.cds;
public class Helper {
public void greet() {
System.out.println("Hello world!");
}
}
接下来在hello-cds
根目录下新建target
目录,并运行如下命令进行编译
javac -d target/classes src/git/snippets/cds/*.java
打包
jar cf target/helloworld.jar -C target/classes .
运行
java -cp target/helloworld.jar git.snippets.cds.App
可以看到控制台打印
Hello world!
接下来开始使用 Application CDS , 我们通过如下命令创建一个helloworld.lst
java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=helloworld.lst -cp target/helloworld.jar git.snippets.cds.App
注意。此命令仅在 OpenJDK 中有效。在 Oracle JDK 中,你会得到一个警告,说 Application CDS 是一个商业特性,你必须先解锁(用-XX:+UnlockCommercialFeatures
)。所以最好使用 OpenJDK,且 JDK 版本必须是10。如果你使用Oracle JDK
,用如下命令代替
java -XX:+UnlockCommercialFeatures -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=helloworld.lst -cp target/helloworld.jar git.snippets.cds.App
可以用记事本打开 helloworld.lst
,发现里面包括了所有相关的class
清单,这里面不仅有 JDK 的 class,也有应用程序的 class。
java/lang/Object
java/lang/String
java/io/Serializable
java/lang/Comparable
java/lang/CharSequence
java/lang/Class
....
git/snippets/cds/App
java/lang/PublicMethods$MethodList
java/lang/PublicMethods$Key
git/snippets/cds/Helper
java/lang/Shutdown
java/lang/Shutdown$Lock
接下来,我们通过 lst 问题创建 JSA 文件,
如果使用OpenJDK 10
,则用如下命令
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=helloworld.lst -XX:SharedArchiveFile=helloworld.jsa -cp target/helloworld.jar
如果使用Oracle JDK 10
,使用如下命令
java -Xshare:dump -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:SharedClassListFile=helloworld.lst -XX:SharedArchiveFile=helloworld.jsa -cp target/helloworld.jar
控制台输出如下信息
narrow_klass_base = 0x0000000800000000, narrow_klass_shift = 3
Allocated temporary class space: 1073741824 bytes at 0x00000008c0000000
Allocated shared space: 3221225472 bytes at 0x0000000800000000
Loading classes to share ...
Loading classes to share: done.
Rewriting and linking classes ...
Rewriting and linking classes: done
Number of classes 689
instance classes = 609
obj array classes = 72
type array classes = 8
Updating ConstMethods ... done.
Removing unshareable information ... done.
Scanning all metaspace objects ...
Allocating RW objects ...
Allocating RO objects ...
Relocating embedded pointers ...
Relocating external roots ...
Dumping symbol table ...
Relocating SystemDictionary::_well_known_klasses[] ...
Removing java_mirror ... done.
mc space: 5656 [ 0.1% of total] out of 65536 bytes [ 8.6% used] at 0x0000000800000000
rw space: 2079360 [ 21.4% of total] out of 2097152 bytes [ 99.2% used] at 0x0000000800010000
ro space: 3934688 [ 40.6% of total] out of 3997696 bytes [ 98.4% used] at 0x0000000800210000
md space: 6160 [ 0.1% of total] out of 65536 bytes [ 9.4% used] at 0x00000008005e0000
od space: 3413720 [ 35.2% of total] out of 3473408 bytes [ 98.3% used] at 0x00000008005f0000
total : 9439584 [100.0% of total] out of 9699328 bytes [ 97.3% used]
生成的 helloworld.jsa 文件仅 9.31 MB 大小
使用jsa
文件重新运行程序
如果使用OpenJDK 10
运行如下命令
java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=helloworld.jsa -cp target/helloworld.jar git.snippets.cds.App
如果使用Oracle JDK 10
,运行如下命令
java -Xshare:on -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:SharedArchiveFile=helloworld.jsa -cp target/helloworld.jar git.snippets.cds.App
控制台输出
Hello world!
源码
参考文档
Java 10 Features (with Examples)
JEP 310: Application Class-Data Sharing
Java SE 10 Application Class-Data Sharing 示例的更多相关文章
- Java SE 10 新增特性
Java SE 10 新增特性 作者:Grey 原文地址:Java SE 10 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- 最新版本的JDK安装和配置(Java SE 10.0.2)
1.废话少说,要么百度JDK,要么直接点传送门http://www.oracle.com/technetwork/java/javase/downloads/index.html.这里需要说的JDK包 ...
- Java SE 13 新增特性
Java SE 13 新增特性 作者:Grey 原文地址:Java SE 13 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 17 新增特性
Java SE 17 新增特性 作者:Grey 原文地址:Java SE 17 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 9 多版本兼容 JAR 包示例
Java SE 9 多版本兼容 JAR 包示例 作者:Grey 原文地址:Java SE 9 多版本兼容 JAR 包示例 说明 Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在 ...
- Java SE 9 模块化示例
Java SE 9 模块化示例 作者:Grey 原文地址:Java SE 9 模块化示例 说明 Java SE 9引入了模块系统,模块就是代码和数据的封装体.模块的代码被组织成多个包,每个包中包含Ja ...
- Java SE 9 新增特性
Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
- Java SE 8 新增特性
Java SE 8 新增特性 作者:Grey 原文地址: Java SE 8 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
- Java SE 11 新增特性
Java SE 11 新增特性 作者:Grey 原文地址:Java SE 11 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
随机推荐
- 【原创】项目四Tr0ll-1
实战流程 1.nmap枚举 nmap -sP 192.168.186.0/24 nmap -p- 192.168.186.142 nmap 192.168.186.142 -p- -sS -sV -A ...
- ExtJS 布局-Fit布局(Fit Layout)
更新记录: 2022年5月31日 第一稿. 1.说明 Fit布局只会显示一个子组件,子项组件的尺寸会拉伸到容器的尺寸.当容器进行调整大小(resized),子组件会自动调整去拉伸到付容器的大小. 注意 ...
- 前端环境搭建nodejs%VScode
nodejs:https://blog.csdn.net/antma/article/details/86104068VScode:https://code.visualstudio.com/Down ...
- 29.MySQL高级SQL语句
MySQL高级SQL语句 目录 MySQL高级SQL语句 创建两个表 SELECT DISTINCT WHERE AND OR IN BETWEEN 通配符 LIKE ORDER BY 函数 数学函数 ...
- 红包雨中:Redis 和 Lua 的邂逅
2018年,王思聪的冲顶大会,西瓜视频的百万英雄,再到映客的芝士超人,直播答题火爆全网. 我服务的一家电商公司也加入了这次热潮,技术团队研发了直播答题功能.答题结束之后,红包会以红包雨的形式落下,用户 ...
- 打通web的三维国产引擎!老子云AMRT,够牛!
AMRT(Auto Mobile Reality Technology)指的是自动化移动现实技术,它是老子云3D模型自动轻量化引擎及轻量化模型格式.模型展示框架.API/SDK的统称.3D研发技术其中 ...
- 【Nginx】Windows平台下配置Nginx服务实现负载均衡
前言:废话不多说了,直接上步骤. 系统环境:win10 测试用的开发环境和服务类型:VS2022 + DotNet 6 + WebApi 1.本地先创建一个webapi项目,用于测试使用. 2.新建一 ...
- ES5的继承和ES6的继承有什么区别?让Babel来告诉你
如果以前问我ES5的继承和ES6的继承有什么区别,我一定会自信的说没有区别,不过是语法糖而已,充其量也就是写法有区别,但是现在我会假装思考一下,然后说虽然只是语法糖,但也是有点小区别的,那么具体有什么 ...
- 微服务追踪SQL(支持Isto管控下的gorm查询追踪)
效果图 SQL的追踪正确插入到微服务的调用链之间 详细记录了SQL的执行内容和消耗时间 搜索SQL的类型 多线程(goroutine)下的追踪效果 在 Kubernetes 中部署微服务后,通过 Is ...
- 记录自己NVIDIA GeForce MX250迷之安装cuda+pytorch成功了
电脑是ubuntu20.4 Pop!_OS 20.04 LTS MX250显卡并没有列在CUDA支持的GPU里 希望文中链接的别人的博客不会消失掉. 安装了英伟达的驱动 参考了这一篇:Ubuntu 安 ...