游侠的博客 游侠的博客
首页
  • 论文笔记
  • 一些小知识点

    • pytorch、numpy、pandas函数简易解释
  • 《深度学习500问》
开发
技术
更多
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ranger

一名在校研究生
首页
  • 论文笔记
  • 一些小知识点

    • pytorch、numpy、pandas函数简易解释
  • 《深度学习500问》
开发
技术
更多
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Vue

  • SpringBoot2

  • JavaWeb

  • SSM

  • SpringBoot3

    • 一、SpringBoot3快速入门
    • 二、SpringBoot核心机制了解
    • 三、SpringBoot的核心技能
    • 四、WebMvcAutoConfiguration原理
    • 五、SpringBootWeb开发-Web场景
    • 六、SpringBootWeb开发-静态资源与路径匹配
    • 七、SpringBootWeb开发-内容协商
    • 八、SpringBootWeb开发-模板引擎
    • 九、SpringBootWeb开发-国际化与错误处理
    • 十、SpringBootWeb开发-嵌入式容器
    • 十一、SpringBootWeb开发-SpringMVC所有常用特性配置
    • 十二、SpringBootWeb开发-Web新特性
    • 十三、SpringBoot-整合SSM场景
    • 十四、SpringBoot-基础特性
    • 十五、SpringBoot-核心原理
    • 十六、SpringBoot场景整合-环境准备
    • 十七、SpringBoot场景整合-Redis
    • 十八、SpringBoot场景整合-接口文档
    • 十九、SpringBoot场景整合-远程调用
    • 二十、SpringBoot场景整合-消息服务
    • 二十一、SpringBoot场景整合-Web安全
    • 二十二、SpringBoot场景整合-可观测性
    • 二十三、SpringBoot场景整合-AOT
      • 1. AOT与JIT
        • 1. Complier 与 Interpreter
        • 2. AOT 与 JIT 对比
        • 3. JVM架构
        • 4. Java的执行过程
        • 1. 流程概要
        • 2. 详细流程
        • 5. JVM编译器
        • 6. 分层编译
      • 2. GraalVM
        • 1. 架构
        • 2. 安装
        • 1. VisualStudio
        • 2. GraalVM
        • 1. 安装
        • 2. 配置
        • 3. 依赖
        • 4. 验证
        • 3. 测试
        • 1. 创建项目
        • 2. 编译镜像
        • 3. Linux平台测试
      • 3. SpringBoot整合
        • 1. 依赖导入
        • 2. 生成native-image
        • 3. 常见问题
  • 技术
  • SpringBoot3
yangzhixuan
2023-06-16
目录

二十三、SpringBoot场景整合-AOT

# 1. AOT与JIT

AOT:Ahead-of-Time(提前编译):程序执行前,全部被编译成机器码

JIT:Just in Time(即时编译): 程序边编译,边运行;

编译:

  • 源代码(.c、.cpp、.go、.java。。。) ===编译=== 机器码

语言:

  • 编译型语言:编译器
  • 解释型语言:解释器

# 1. Complier 与 Interpreter

Java:半编译半解释

https://anycodes.cn/editor

image

对比项 编译器 解释器
机器执行速度 快,因为源代码只需被转换一次 慢,因为每行代码都需要被解释执行
开发效率 慢,因为需要耗费大量时间编译 快,无需花费时间生成目标代码,更快的开发和测试
调试 难以调试编译器生成的目标代码 容易调试源代码,因为解释器一行一行地执行
可移植性(跨平台) 不同平台需要重新编译目标平台代码 同一份源码可以跨平台执行,因为每个平台会开发对应的解释器
学习难度 相对较高,需要了解源代码、编译器以及目标机器的知识 相对较低,无需了解机器的细节
错误检查 编译器可以在编译代码时检查错误 解释器只能在执行代码时检查错误
运行时增强 无 可以动态增强

# 2. AOT 与 JIT 对比

JIT AOT
优点 1.具备实时调整能力
2.生成最优机器指令
3.根据代码运行情况优化内存占用
1.速度快,优化了运行时编译时间和内存消耗
2.程序初期就能达最高性能
3.加快程序启动速度
缺点 1.运行期边编译速度慢
2.初始编译不能达到最高性能
1.程序第一次编译占用时间长
2.牺牲高级语言一些特性

在 OpenJDK 的官方 Wiki 上,介绍了HotSpot 虚拟机一个相对比较全面的、**即时编译器(JIT)**中采用的优化技术列表 (opens new window)。

image

image

可使用:-XX:+PrintCompilation 打印JIT编译信息

# 3. JVM架构

.java === .class === 机器码

image

JVM: 既有解释器,又有编译器(JIT:即时编译);

# 4. Java的执行过程

建议阅读:

  • 美团技术:https://tech.meituan.com/2020/10/22/java-jit-practice-in-meituan.html
  • openjdk官网:https://wiki.openjdk.org/display/HotSpot/Compiler

# 1. 流程概要

IR:中间表示层

image

解释执行的代码调用次数达到阈值就进行编译,放到代码缓存里

# 2. 详细流程

热点代码:调用次数非常多的代码

在运行代码的时候可以添加一些额外参数改变内部的一些细节

image

# 5. JVM编译器

JVM中集成了两种编译器,Client Compiler 和 Server Compiler;

  • Client Compiler注重启动速度和局部的优化
  • Server Compiler更加关注全局优化,性能更好,但由于会进行更多的全局分析,所以启动速度会慢。

Client Compiler:

  • HotSpot VM带有一个Client Compiler C1编译器
  • 这种编译器启动速度快,但是性能比较Server Compiler来说会差一些。
  • 编译后的机器码执行效率没有C2的高

Server Compiler:

  • Hotspot虚拟机中使用的Server Compiler有两种:C2 和 Graal。
  • 在Hotspot VM中,默认的Server Compiler是C2编译器。

# 6. 分层编译

Java 7开始引入了分层编译(Tiered Compiler)的概念,它结合了C1和C2的优势,追求启动速度和峰值性能的一个平衡。分层编译将JVM的执行状态分为了五个层次。五个层级分别是:

  1. 解释执行。

  2. 执行不带profiling的C1代码。

  3. 执行仅带方法调用次数以及循环回边执行次数profiling的C1代码。

  4. 执行带所有profiling的C1代码。

  5. 执行C2代码。

profiling就是收集能够反映程序执行状态的数据。其中最基本的统计数据就是方法的调用次数,以及循环回边的执行次数。

image

  • 图中第①条路径,代表编译的一般情况,热点方法从解释执行到被3层的C1编译,最后被4层的C2编译。
  • 如果方法比较小(比如Java服务中常见的getter/setter方法),3层的profiling没有收集到有价值的数据,JVM就会断定该方法对于C1代码和C2代码的执行效率相同,就会执行图中第②条路径。在这种情况下,JVM会在3层编译之后,放弃进入C2编译,直接选择用1层的C1编译运行。
  • 在C1忙碌的情况下,执行图中第③条路径,在解释执行过程中对程序进行profiling ,根据信息直接由第4层的C2编译。
  • 前文提到C1中的执行效率是1层>2层>3层,第3层一般要比第2层慢35%以上,所以在C2忙碌的情况下,执行图中第④条路径。这时方法会被2层的C1编译,然后再被3层的C1编译,以减少方法在3层的执行时间。
  • 如果编译器做了一些比较激进的优化,比如分支预测,在实际运行时发现预测出错,这时就会进行反优化,重新进入解释执行,图中第⑤条执行路径代表的就是反优化。

总的来说,C1的编译速度更快,C2的编译质量更高,分层编译的不同编译路径,也就是JVM根据当前服务的运行情况来寻找当前服务的最佳平衡点的一个过程。从JDK 8开始,JVM默认开启分层编译。

云原生:Cloud Native(将一个程序的服务分散到多台机器上)

为了保证替换某个jar包后服务的执行速度,对Java进行了小改版;

最好的效果:

存在的问题:

  • java应用如果用jar,解释执行,热点代码才编译成机器码;初始启动速度慢,初始处理请求数量少。
  • 大型云平台,要求每一种应用都必须秒级启动。每个应用都要求效率高。

希望的效果:

  • java应用也能提前被编译成机器码,随时急速启动,一启动就急速运行,最高性能

  • 编译成机器码的好处:

    • 另外的服务器还需要安装Java环境
    • 编译成机器码的,可以在这个平台 Windows X64 直接运行。

原生镜像:native-image(机器码、本地镜像)

  • 把应用打包成能适配本机平台 的可执行文件(机器码、本地镜像)

# 2. GraalVM

https://www.graalvm.org/

GraalVM是一个高性能的JDK,旨在加速用Java和其他JVM语言编写的应用程序的执行,同时还提供JavaScript、Python和许多其他流行语言的运行时。

GraalVM提供了两种运行Java应用程序的方式:

    1. 在HotSpot JVM上使用Graal即时(JIT)编译器
    1. 作为预先编译(AOT)的本机可执行文件运行(本地镜像)。

GraalVM的多语言能力使得在单个应用程序中混合多种编程语言成为可能,同时消除了外部语言调用的成本。

# 1. 架构

GraalVm除了支持Java系的语言,还支持其他的语言

image

# 2. 安装

跨平台提供原生镜像原理:

不同平台安装GraalVM,并安装对应的本地集成环境

image

# 1. VisualStudio

https://visualstudio.microsoft.com/zh-hans/free-developer-offers/

image

image

别选中文

image

image

记住你安装的地址;

# 2. GraalVM

# 1. 安装

下载 GraalVM + native-image

image

image

image

image

# 2. 配置

修改 JAVA_HOME 与 Path,指向新bin路径

image

image

验证JDK环境为GraalVM提供的即可:

image

# 3. 依赖

安装 native-image 依赖:

  1. 网络环境好:参考:https://www.graalvm.org/latest/reference-manual/native-image/#install-native-image
gu install native-image
1
  1. 网络不好,使用我们下载的离线jar;native-image-xxx.jar文件
gu install --file native-image-installable-svm-java17-windows-amd64-22.3.2.jar
1
# 4. 验证
native-image
1

# 3. 测试

# 1. 创建项目

    1. 创建普通java项目。编写HelloWorld类;
    • 使用mvn clean package进行打包
    • 确认jar包是否可以执行java -jar xxx.jar
    • 可能需要给 MANIFEST.MF添加 Main-Class: 你的主类

# 2. 编译镜像

  • 编译为原生镜像(native-image):使用native-tools终端

image

#从入口开始,编译整个jar
native-image -cp boot3-15-aot-common-1.0-SNAPSHOT.jar com.atguigu.MainApplication -o Haha

#编译某个类【必须有main入口方法,否则无法编译】
native-image -cp .\classes org.example.App
1
2
3
4
5

# 3. Linux平台测试

    1. 安装gcc等环境
yum install lrzsz
sudo yum install gcc glibc-devel zlib-devel
1
2
    1. 下载安装配置Linux下的GraalVM、native-image
    • 下载:https://www.graalvm.org/downloads/
    • 安装:GraalVM、native-image
    • 配置:JAVA环境变量为GraalVM
tar -zxvf graalvm-ce-java17-linux-amd64-22.3.2.tar.gz -C /opt/java/

sudo vim /etc/profile
#修改以下内容
export JAVA_HOME=/opt/java/graalvm-ce-java17-22.3.2
export PATH=$PATH:$JAVA_HOME/bin

source /etc/profile
1
2
3
4
5
6
7
8
    1. 安装native-image
gu install --file native-image-installable-svm-java17-linux-amd64-22.3.2.jar
1
    1. 使用native-image编译jar为原生程序
native-image -cp xxx.jar org.example.App
1

# 3. SpringBoot整合

# 1. 依赖导入

 <build>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
1
2
3
4
5
6
7
8
9
10
11
12

# 2. 生成native-image

1、运行aot提前处理命令:mvn springboot:process-aot

2、运行native打包:mvn -Pnative native:build

# 推荐加上 -Pnative
mvn -Pnative native:build -f pom.xml
1
2

image

# 3. 常见问题

可能提示如下各种错误,无法构建原生镜像,需要配置环境变量;

  • 出现cl.exe找不到错误
  • 出现乱码
  • 提示no include path set
  • 提示fatal error LNK1104: cannot open file 'LIBCMT.lib'
  • 提示 LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
  • 提示各种其他找不到

需要修改三个环境变量:Path、INCLUDE、lib

  • 1、 Path:添加如下值
  • C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\Hostx64\x64
  • 2、新建INCLUDE环境变量:值为
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\winrt
1

image

  • 3、新建lib环境变量:值为
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\lib\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64
1

image

编辑 (opens new window)
上次更新: 2024/05/30, 07:49:34
二十二、SpringBoot场景整合-可观测性

← 二十二、SpringBoot场景整合-可观测性

最近更新
01
tensor比较大小函数
05-30
02
Large Language Models can Deliver Accurate and Interpretable Time Series Anomaly Detection
05-27
03
半监督学习经典方法 Π-model、Mean Teacher
04-10
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Ranger | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式