java 位运算取8位_Java 9 AOT 试用:仅支持 64 位 Linux和java.base 模块编译

d61ec39f5681ca98fe148925ecd8a301.png

Java 9 引入了 aot 编译方式,能够将 class 文件直接编译成可执行二进制文件。目前 Java 9 的 early access 版本已经提供了编译工具,让我们来看看它的功能吧。

注意:按照 JEP 295 描述,目前版本的 AOT,仅支持 64 位 Linux 操作系统。

jaotc 使用

首先需要下载最新的Java 9(JDK),本文编写时,最新版本是Build 152。下载好的JDK 只需要解压即可使用,特别注意使用前设置好 PATH和JAVA_HOME两个环境变量,避免和机器上已经安装的 JDK 混淆。笔者安装到了 $HOME/bin/jdk-9,并设置了:

export PATH=~/bin/jdk-9/bin:$PATH

export JAVA_HOME=~/bin/jdk-9

需要使用jaotc,首先需要有个测试类,首先从 Hello World 开始:

class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

代码非常简单,但是在执行 jaotc 之前,还需要将其编译成 class 文件,直接使用 javac 即可:

$ javac HelloWorld.java

执行成功之后,会生成 HelloWorld.class 文件。此时直接使用 java 命令,已经可以正常运行这个类:

$ java HelloWorld

Hello World!

这时,就可以基于这个 class 文件,通过jaotc命令将其编译成二进制文件了。

$ jaotc --output libHelloWorld.so HelloWorld.class

如果一切正常,会生成 libHelloWorld.so 文件。

如果出现类似Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/babydragon/bin/jdk-9/lib/libjelfshim.so: libelf.so.1: 无法打开共享对象文件: 没有那个文件或目录的错误,是因为jaotc需要依赖 libelf 动态链接库来创建 elf 文件(最终生成的 libHelloWorld.so 文件是一个静态链接的 elf 文件)。笔者使用的是 Gentoo 系统,需要安装 dev-libs/elfutils 包,以提供 libelf.so 这个动态连接库。安装之后可以通过ldd命令进行确认:

$ ldd $JAVA_HOME/lib/libjelfshim.so

linux-vdso.so.1 (0x00007ffd001f3000)

libelf.so.1 => /usr/lib64/libelf.so.1 (0x00007f25ea2ce000)

libc.so.6 => /lib64/libc.so.6 (0x00007f25e9f35000)

libz.so.1 => /lib64/libz.so.1 (0x00007f25e9d1d000)

/lib64/ld-linux-x86-64.so.2 (0x0000562318d51000)

前面通过jaotc命令成功生成了 libHelloWorld.so。虽然命令里面参照 JEP 295 的示例将生成的文件后缀设置成了 so,但如果使用ldd命令查看,会发现它其实是一个静态链接库:

$ ldd libHelloWorld.so

statically linked

通过nm命令,可以看见代码段中的函数入口:

$ nm libHelloWorld.so

0000000000002420 t HelloWorld.()V

0000000000002520 t HelloWorld.main([Ljava/lang/String;)V

最后,需要执行时需要通过参数-XX:AOTLibrary参数指定需要加载的经过 aot 预编译好的共享库文件:

java -XX:AOTLibrary=./libHelloWorld.so HelloWorld

注意:虽然已经将整个 HelloWorld 类都通过 jaotc 编译成共享库文件,运行时仍然需要依赖原有的 HelloWorld.class 文件。

此时执行的输出,和之前不使用 AOT 的输出完全相同。

来把大的——将 java.base 模块编译成 AOT 库

JEP 295 中已经说明,在 Java 9 初始发布的时候,只保证 java.base 模块可以被编译成 AOT 库。

继续参照 JEP 295,创建 java.base-list.txt 文件,内容主要是排除一些编译有问题的方法,具体内容参照原文。

然后执行命令:

jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g --compile-for-tiered --info --compile-commands java.base-list.txt --output libjava.base-coop.so --module java.base

在笔者的机器上(i7-6600U + 16G 内存 + 256G NVMe SSD),排除上述方法之后,编译时间大约为 9 分多钟。

48878 methods compiled, 4 methods failed (497771 ms)

Parsing compiled code (1126 ms)

Processing metadata (15811 ms)

Preparing stubs binary (0 ms)

Preparing compiled binary (104 ms)

Creating binary: libjava.base-coop.o (5611 ms)

Creating shared library: libjava.base-coop.so (7306 ms)

Total time: 542536 ms

完成之后,就可以使用 AOT 版本的 java.base 模块:

java -XX:AOTLibrary=java_base/libjava.base-coop.so,./libHelloWorld.so HelloWorld

同样,针对 AOT,jvm 也新增了参数打印哪些方法是通过加载 AOT 预编译库执行。

java -XX:+PrintAOT -XX:AOTLibrary=java_base/libjava.base-coop.so,./libHelloWorld.so HelloWorld

输出可以和不使用 java.base 的 AOT 进行比较,发现不使用 java.base 的 AOT 库,只能会加载 libHelloWorld.so 中对应的方法。

$ java -XX:+PrintAOT -XX:AOTLibrary=./libHelloWorld.so HelloWorld

11 1 loaded ./libHelloWorld.so aot library

105 1 aot[ 1] HelloWorld.()V

105 2 aot[ 1] HelloWorld.main([Ljava/lang/String;)V

Hello World!

$ java -XX:+PrintAOT -XX:AOTLibrary=java_base/libjava.base-coop.so,./libHelloWorld.so HelloWorld

13 1 loaded java_base/libjava.base-coop.so aot library

13 2 loaded ./libHelloWorld.so aot library

[Found [Z in java_base/libjava.base-coop.so]

[Found [C in java_base/libjava.base-coop.so]

[Found [F in java_base/libjava.base-coop.so]

[Found [D in java_base/libjava.base-coop.so]

[Found [B in java_base/libjava.base-coop.so]

[Found [S in java_base/libjava.base-coop.so]

[Found [I in java_base/libjava.base-coop.so]

[Found [J in java_base/libjava.base-coop.so]

31 1 aot[ 1] java.lang.Object.()V

31 2 aot[ 1] java.lang.Object.finalize()V

...

输出太长,节选部分输出,我们可以看见 java 基础类及其方法都通过 AOT 的方式进行加载。

实用吗?

目前 AOT 的局限有:

仅支持 64 位 Linux 操作系统:这个问题不是很大,毕竟大部分线上服务器都能够满足;

操作系统需要预装 libelf 库,以确保能够生成 elf 文件:这个问题也不大,仅生成时需要;

AOT 编译和执行环境需要相同:毕竟是二进制文件,引入了平台相关性;

Java 9 最初发布时,只支持 java.base 模块可以编译成 AOT 库;

目前只支持 G1 和 Parallel GC 两种 GC 方式:前面没有提到,AOT 编译时的 JVM 参数和运行时需要相同,也包括 GC 方式,也就是说如果用了 AOT,JVM 实际运行时也只能使用这两种 GC 方式之一;

可能会无法编译通过动态生成 class 文件或者修改字节码的 java 代码(如 lambda 表达式、反射调用等):这个可能会比较坑,后面会讲到;

JVM 运行时参数设置必须和 AOT 库编译时相同;

AOT 可能带来的好处,是 JVM 加载这些已经预编译成二进制库之后,可以直接调用,而无需再将其运行时编译成二进制码。理论上,AOT 的方式,可以减少 JIT 带来的预热时间,减少 Java 应用长期给人带来的“第一次运行慢”感觉。

不过,本文使用的 HelloWorld 过于简单,无法通过对比得出 AOT 是否可以减少 JVM 初始化时间。笔者尝试对一个小型 springboot 应用进行 AOT 化,但是 springboot 框架本身无法在 Java 9 中运行。同时直接对 spring-core 的 jar 包执行 jaotc 也因为各种依赖问题而失败。

经过各种尝试,目前 Java 9 的 AOT 功能还处于很初步的阶段:

缺少 maven 等管理工具集成,无法方便的对项目指定 jar 或者 class 文件比构建 AOT 库;

大型框架还没有官方支持,构建 AOT 库难度比较高;

大型框架如果直接提供 AOT 库,可能会因为由特定平台构建,而在本地无法使用;

期待 Java 9 正式发布的时候,能够对 AOT 有更好的支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

友元关系可以继承_私生子也有继承权!非婚生子女的继承关系如何认定?

阅读本文前,请您先点击上面的“蓝色字体”,再点击“关注”,这样您就可以继续免费收到文章了。每天都会有分享,都是免费订阅,请您放心关注。注:本文转载自网络,不代表本平台立场,仅供…

mysql100多个字段如何优化_MySQL 调优/优化的 100 个建议

MySQL是一个强大的开源数据库。随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈。这里提供 101 条优化 MySQL 的建议。有些技巧适合特定的安装环境,但是思路是相通的。我已经将它们分成了几类以帮助你理解。MySQL监控MySQL服务器硬件和OS(操作系统)调优&…

普罗米修斯监控java项目_java学到什么程度可以出去实习?

把基础的知识学完,然后再学个框架,比如常见的SSH,SSM之类的,自己能用这个框架做个简单的项目,就可以了简单的来说就是把下方的视频教程学完就可以找工作了(需要完整的资料可以找up)Java零基础初…

mysql中 唯一约束的关键字是_mysql的约束

在mysql设计表中,有个概念叫做约束什么是约束约束英文:constraint约束实际上就是表中数据的限制条件约束种类mysql的约束大概分为以下几种:非空约束(not null)唯一性约束(unique)主键约束(primary key) PK外键约束(foreign key) FK检查约束(目前MySQL不支持、Oracle…

叉乘点乘混合运算公式_小学36年级必须掌握的数学公式和概念口诀,替孩子收藏一下!...

小学数学需要记住的知识点还是比较多的,看到这些知识点,很多孩子都觉得枯燥,不愿意用心去记。如果我们把一种新的、有趣的记忆方法教给孩子,孩子也会变得有兴趣,因为兴趣是最好的老师。一、20以内进位加法看大数&#…

python图像数独_Python图像识别+KNN求解数独的实现

Python-opencvKNN求解数独最近一直在玩数独,突发奇想实现图像识别求解数独,输入到输出平均需要0.5s。整体思路大概就是识别出图中数字生成list,然后求解。输入输出demo数独采用的是微软自带的Microsoft sudoku软件随便截取的图像,…

上位机与1200组态步骤_西门子1200的HSC的应用实例!

高速计数器寻址CPU 将每个高速计数器的测量值,存储在输入过程映像区内,数据类型为 32 位双整型有符号数,用户可以在设备组态中修改这些存储地址,在程序中可直接访问这些地址,但由于过程映像区受扫描周期影响&#xff0…

cmd代码表白_手把手教你把Python代码转成exe

【文末有福利】很多刚入门的盆友都有疑惑怎么把Python代码转成可执行的exe?,这里行哥统一解决一下这个问题1.在cmd里安装pyintsaller包2.在cmd里输入打包成exe的命令3.问题总结4. pyintsaller --help5. end1.在cmd里安装pyintsaller包第一步安装将Python…

searchview 点击后被覆盖_03实战Jacoco统计代码覆盖

本篇内容主要介绍:在gradle项目中添加jacoco来了解工程的代码覆盖情况。自动化的统计代码覆盖情况,有助于将焦点问题可视化,从而决定什么时候采取什么动作进行改进。Jacoco可以方面的添加在测试执结束,进行代码覆盖率的统计。如果…

电脑功耗软件_台式电脑配置详解!

近期有许多做设计的朋友问我,怎么配一台工作用的电脑,今天就给大家介绍一下电脑的各个组成部分。电脑核心配置,一般指CPU、主板、显卡三大件,一般笔记本电脑不需要考虑主板,只需考虑CPU和显卡两大件。1.CPU的选择现在的…

spring定时器突然不执行了_非标自动化设备之PLC定时器的时间和程序扫描周期

扫描周期是PLC本身执行指令时的周转时间。PLC执行指令按梯形图是从左向右,从上到下执行。每执行一遍就顺便扫描一遍所有元件状态并按指令执行相应动作。这个是需要时间吧,把这个时间叫扫描周期。并如此无限循环下去。当然扫描周期越短,PLC性能…

python入门小游戏之跳一跳_从零基础开始,用python手把手教你玩跳一跳小游戏,直接打出高分...

这对于很多人来说,可能是已经过时的游戏,但是对于python入门来说,却是一个非常值得学习的项目。TONOW收集了很多有关python入门的项目案例,包含了相应的教程和源码,哪怕你从未接触编程,也通过这些教程&…

如何反映两条曲线的拟合精度_用水平仪如何检测导轨的直线度?

1、水平仪的原理及用途: 气泡型水平仪的水准管是由玻璃制成,水准管内壁是一个具有一定曲率半径的曲面,管内装有液体,当水平仪发生倾斜时,水准管中气泡就向水平仪升高的一端移动,从而确定水平面的…

嵌套查询和连接查询的效率_Elasticsearch 7.x Nested 嵌套类型查询 | ES 干货

一、什么是 ES Nested 嵌套Elasticsearch 有很多数据类型,大致如下:基本数据类型: string 类型。ES 7.x 中,string 类型会升级为:text 和 keyword。keyword 可以排序;text 默认分词,不可以排序。…

c++程序设计_基于proteus的51单片机开发实例30-模块化程序设计

1. 基于proteus的51单片机开发实例30-模块化程序设计1.1. 实验目的模块化程序设计不知不觉我们的51单片机开发实例已经进行到第三十篇了,是时候进行一个总结和反思了,总结什么?反思什么呢?我们先从程序结构开始吧。总结在前面的29…

反序列化的时候出现eof exception_FastJson序列化时候出现了$ref?还不赶紧学习下...

最近在使用fastjson时候遇到一个问题,后台的数据转化为json字符串后发送到前端时候出现了$ref字样的东西,后来明白了这是引用,下面详细介绍下。一、一个简单的例子先来上一段代码,运行后打印的结果可能出乎意料,代码如…

阿里云 linux mysql数据库_Linux Mysql数据库安全配置

Linux Mysql数据库安全配置目录:1.修改mysql管理员账号root的密码(2种方法)2.修改mysql管理员账号root3.mysql管理员root账号密码遗忘解决办法(2种方法)4.创建数据库用户(3种方法)5.mysql数据库权限管理本地权限网络权限撤销权限删除用户一、修改mysql管理员账号roo…

快速锁屏电脑快捷键_一学就会的8个电脑快捷键一定要掌握!堪称“高效”神器...

日常工作中,电脑是我们常用的设备,为了提高工作效率常常需要牢记一些电脑快捷键,那么有哪些电脑快捷键值得我们牢记呢?下面分享8个实用的电脑快捷键,关键时刻省时又省力哟!#1 WindowsL 快速锁屏一般用在暂时…

left join 重复数据_Python数据分析整理小节

一、数据读取1、读写数据库数据读取函数:pandas.read_sql_table(table_name, con, schemaNone, index_colNone, coerce_floatTrue, columnsNone)pandas.read_sql_query(sql, con, index_colNone, coerce_floatTrue)pandas.read_sql(sql, con, index_colNone, coerce_floatTrue,…

win10文件显示后缀名_Win10一开机,内存占用竟高达60%?你可以尝试这样做

说到win10一开机,内存占用竟高达60%,你是怎么处理的呢?深受其害的朋友就此大展身手了,瞅瞅!A:我16G内存,也是开机占用了70%多。百度找了很多方法都是不相关的答案,后来发现了关闭快速…