为了账号安全,请及时绑定邮箱和手机立即绑定

aot的常规使用

标签:
Java

在熟悉了aot的一些基本操作以及一些使用模式后,我们看看常规的操作是怎么样的。

对核心类库编译

java核心类库可以说是调用比较频繁的代码,所以把核心类库进行编译,可以有效的提升启动速度。

jaotc --output libjava.base.so --module java.base

一般情况下,jdk是保证了核心类库的编译是没有问题的。上面的指令除非用的预览版本,那都是正常的。

合理设置参数

jaotc可以使用-J指定运行时参数,官方的例子中使用了gc参数和压缩指针参数。

jaotc   -J-XX:-UseCompressedOops --output libtest.so AotTest.class

如果运行时没有-XX:-UseCompressedOops日志中会打印出一个异常。

Shared file ./libtest.so error: UseCompressedOops has different value 'false' from current 'true'
    832    1     skipped ./libtest.so  aot library

gc的也同理。
哪些运行时参数是必须编译时就设置的,这个我自己测试了-Xmx这些,是可以运行的。现在发现的其实就是那两个参数,这个只能说实践中慢慢确认了。
这里也就是出现了一个问题,我们的程序不一定都要用G1,有的也需要使用ps,堆小的是需要开启压指针的,堆大的确实不需要。针对这种情况,我们能做的就是把情况和组合枚举一下,然后编译出多个版本,启动的时候指定不同的版本,官方就推荐这么做的,甚至他还举了例子。

-XX:-UseCompressedOops -XX:+UseG1GC :       libjava.base.so
-XX:+UseCompressedOops -XX:+UseG1GC :       libjava.base-coop.so
-XX:-UseCompressedOops -XX:+UseParallelGC : libjava.base-nong1.so
-XX:+UseCompressedOops -XX:+UseParallelGC : libjava.base-coop-nong1.so

应该庆幸参数可能就这么少,如果运行时特别多的话,编译起来估计要疯的,得写脚本做循环遍历。然后用的时候得按照规则加载出合适的库,大部分时间都花在了脚本匹配上了,而且还得打开-XX:+PrintAOT,这个错误并不会让程序失败停止。还需要做日志分析。所以说这个用起来确认正确性还真是一个麻烦的事情。

aot与反射

我写了一个比较简单的demo,发现aot是支持反射的。

import java.lang.reflect.Field;

public class AotTest {
    public static void main(String[] args) throws Exception {
        Class<?> testB=Class.forName("TestB");
           Field fields = testB.getDeclaredField("SS");
            fields.setAccessible(true);
              String ss = (String) fields.get(null);
              System.out.println(ss);

    }
}

public class TestB{

	private final static String SS="ggg";
	public static void main(String[] args) {
		System.out.println("this is TestB");
	}
}

我们把两个class文件打到一个库里。

jaotc  --output libtest.so AotTest.class TestB.class

执行我们看到,TestB也是可以正常执行的。

java  -XX:+PrintAOT  -XX:AOTLibrary=./libtest.so AotTest
    747    1     loaded    ./libtest.so  aot library
    828    1     aot[ 1]   AotTest.<init>()V
    828    2     aot[ 1]   AotTest.main([Ljava/lang/String;)V
    828    3     aot[ 1]   TestB.<init>()V
    828    4     aot[ 1]   TestB.main([Ljava/lang/String;)V
ggg

aot与lambda

import java.lang.reflect.Field;

public class AotTest {
    public static void main(String[] args) throws Exception {
        Class<?> testB=Class.forName("TestB");
           Field fields = testB.getDeclaredField("SS");
            fields.setAccessible(true);
              String ss = (String) fields.get(null);
              System.out.println(ss);


              MathOperation addition = (int a, int b) -> a + b;
              addition.operation(1, 2);
    }
}

interface MathOperation {
    int operation(int a, int b);
}

沿用上面的例子,加了一个lambda。我们看看结果。

$ java  -XX:+PrintAOT  -XX:AOTLibrary=./libtest.so AotTest
    673    1     loaded    ./libtest.so  aot library
    752    1     aot[ 1]   AotTest.lambda$main$0(II)I
    752    2     aot[ 1]   AotTest.<init>()V
    752    3     aot[ 1]   AotTest.main([Ljava/lang/String;)V
    753    4     aot[ 1]   TestB.<init>()V
    753    5     aot[ 1]   TestB.main([Ljava/lang/String;)V
ggg

我们发现lambda也是可以正常运行的。

总结

以上的案例都是基于jdk11做的,相比9刚出aot的时候,支持力度更好,基本的反射以及lambda都是可以正常运行。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
1.6万
获赞与收藏
380

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消