概念

AOT是Ahead-of-Time的缩写,AOT是将C#程序提前编译为机器代码(通常为平台特定的二进制文件),在应用程序启动之前完成编译过程。

微软官方文档是这样说的

将应用程序发布为本机 AOT 会生成一个自包含的应用程序,并且已提前 (AOT) 编译为本机代码。原生 AOT 应用程序具有更快的启动时间和更小的内存占用。这些应用可以在未安装 .NET 运行时的计算机上运行。

原生 AOT 的优势对于具有大量已部署实例的工作负载(例如云基础设施和超大规模服务)最为明显。.NET 8 添加了对本机 AOT 的 ASP.NET Core 支持。

本机 AOT 部署模型使用预先编译器在发布时将 IL 编译为本机代码。本机 AOT 应用程序在应用程序运行时不使用实时 (JIT) 编译器。本机 AOT 应用程序可以在不允许 JIT 的受限环境中运行。本机 AOT 应用程序以特定的运行时环境为目标,例如 Linux x64 或 Windows x64,就像发布自包含应用程序一样。

C# AOT部署和JIT部署两种不同的编译和部署方式对比

AOT(Ahead-of-Time)部署:

AOT是将C#程序提前编译为机器代码(通常为平台特定的二进制文件),在应用程序启动之前完成编译过程。

优点:

  1. 启动速度快:由于已经提前编译成机器代码,应用程序可以直接执行,减少了启动时的编译延迟。
  2. 内存占用低:不需要在运行时为JIT编译分配额外内存,避免了JIT编译过程中可能的内存开销。
  3. 跨平台支持:AOT编译后,可以生成特定平台的本地代码,能够更好地支持跨平台部署。
  4. 安全性:由于所有的代码已经提前编译为机器代码,JIT编译的潜在安全风险(如代码注入等)较少。
  5. 性能稳定:AOT编译会优化代码,尤其适用于性能要求严格的场景,能够提供更稳定的执行性能。

缺点:

  1. 编译时间长:AOT需要在部署前进行编译,可能导致部署的时间较长。
  2. 平台依赖:AOT编译会生成特定平台的机器码,因此跨平台部署需要针对每个平台生成不同版本的代码。
  3. 灵活性较低:JIT可以根据运行时的环境和数据进行动态优化,而AOT在编译时就决定了优化策略,缺乏运行时调整的灵活性。

JIT(Just-in-Time)部署:

JIT是在应用程序运行时将中间语言(IL)编译为机器代码,编译过程是动态发生的。

优点:

  1. 快速开发:JIT编译能够即时将中间语言编译为本地代码,因此可以更灵活地进行开发和调试。
  2. 跨平台支持:通过运行时环境(如.NET Core或Mono),JIT可以支持多平台的代码编译,而不需要为每个平台单独编译。
  3. 运行时优化:JIT可以根据应用程序的运行环境和具体数据动态生成优化的机器代码,可能会实现更高的性能,尤其是在具有不同负载的应用场景下。
  4. 更高的灵活性:JIT可以在运行时处理平台和硬件特性,为应用程序生成最合适的代码。

缺点:

  1. 启动时间慢:JIT编译需要在运行时将代码编译为机器代码,因此启动速度较慢,特别是在初次运行时。
  2. 额外内存开销:JIT编译需要在内存中保存编译生成的机器代码,这可能导致内存占用较高。
  3. 性能波动:由于JIT编译是在运行时进行的,可能导致执行过程中存在性能波动,尤其是在复杂的代码路径上。

总结:

  • AOT部署适用于需要快速启动、内存占用较低、性能要求稳定的场景,例如嵌入式设备或资源受限的应用。它的主要缺点是编译时间较长以及缺乏运行时优化的灵活性。
  • JIT部署适用于需要较高灵活性、支持多平台和快速开发的场景,它能动态优化性能,但启动时间较长,并可能带来额外的内存开销。

选择AOT还是JIT部署,需要根据具体的应用场景、性能需求、开发周期和平台要求来权衡。

实操

创建一个解决方案,创建两个控制台项目,一个启用AOT,一个不启用

未启用AOT的csproj文件内容

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup> </Project>

启用AOT的csproj文件内容

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup> </Project>

通过对比可以发现就这个配置 <PublishAot>true</PublishAot>启用AOT

参考官方文档:

https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8

AOT部署一般要在csproj增加如下配置

 <PublishAot>true</PublishAot>
<IsAotCompatible>true</IsAotCompatible>
<StripSymbols>false</StripSymbols>
<PlatformTarget>x64</PlatformTarget>
  • <PublishAot>true</PublishAot> 此属性在发布期间启用本机 AOT 编译
  • <IsAotCompatible>true</IsAotCompatible> 该属性用于指示库是否与本机 AOT 兼容
  • <StripSymbols>false</StripSymbols> 调试文件对于在调试器下运行应用程序或检查故障转储是必需的。在类 Unix 平台上,将该属性设置为在本机二进制文件中包含调试信息。包含调试信息会使本机二进制文件更大
  • <PlatformTarget>x64</PlatformTarget> 目标平台内容是AnyCPU、x86、x64、ARM32、ARM64,一般选择x64/AnyCPU即可,其它平台看场景

发布到Win系统的AOT

发布命令参考:

https://learn.microsoft.com/zh-cn/dotnet/core/deploying/ready-to-run

https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish

1.直接使用VS进行发布

2.使用dotnet命令

使用cmd进入到在csproj文件夹目录,执行dotnet命令

dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true

发布到Liunx系统的AOT

如果直接在VS 2022上发布到Liunx的AOT部署会报下面错误

Cross-OS native compilation is not supported.

1、在 os-linux-ubuntu-2204 上安装 .NET SDK 或 .NET 运行时

使用包管理器安装

参考文档:

https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-ubuntu-install?tabs=dotnet9&pivots=os-linux-ubuntu-2204

添加存储库

sudo add-apt-repository ppa:dotnet/backports

安装SDK

sudo apt-get update && \
sudo apt-get install -y dotnet-sdk-9.0

安装运行时

#ASP.NET Core 运行时
sudo apt-get update && \
sudo apt-get install -y aspnetcore-runtime-9.0
#.NET 运行时
sudo apt-get install -y dotnet-runtime-9.0

使用脚本安装

参考文档

https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-scripted-manual#scripted-install

# 通过 wget 下载脚本
wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh
#可执行文件运行的权限
chmod +x ./dotnet-install.sh

此脚本默认安装最新的长期支持 (LTS) SDK 版本,即 .NET 8。 若要安装最新版本(可能不是 (LTS) 版本),请使用 --version latest 参数。

./dotnet-install.sh --version latest
# 若要安装 .NET 运行时而非 SDK,请使用 --runtime 参数。
./dotnet-install.sh --version latest --runtime aspnetcore
# 可以通过 --channel 参数更改特定主要版本来指示特定版本。 以下命令安装 .NET 9.0 SDK。
./dotnet-install.sh --channel 9.0

手动安装

参考文档:

https://blog.csdn.net/qq_36437991/article/details/120389823

下载SDK/runtime地址:https://dotnet.microsoft.com/zh-cn/download/dotnet/9.0

这里下载的是dotnet-sdk-9.0.102-linux-x64.tar.gz

# 创建文件夹
sudo mkdir -p /usr/dotnet/9.0.102
# 解压文件
sudo tar xzf dotnet-sdk-9.0.102-linux-x64.tar.gz -C /usr/dotnet/9.0.102/
# 使用vim修改/etc/profile文件/或者使用SSH更改文件
sudo vim /etc/profile # 在/etc/profile文件下增加下面内容
export DOTNET_HOME=/usr/dotnet/9.0.102
export PATH=${DOTNET_HOME}:$PATH
# 重新加载系统级别的环境配置文件
source /etc/profile

2、检查安装.NET的版本

参考文档:

https://learn.microsoft.com/zh-cn/dotnet/core/install/how-to-detect-installed-versions?pivots=os-linux

# 查看版本
dotnet --version
# 检查 SDK 版本
dotnet --list-sdks
# 检查运行时版本
dotnet --list-runtimes

3、 安装C++编译工具

参考文档:

https://blog.darkthread.net/blog/publish-native-aot-on-linux/

https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/?tabs=linux-ubuntu%2Cnet9plus

sudo apt-get install clang zlib1g-dev

4、把解决方案代码上传到Linux系统某个文件夹上并转到要发布的项目csproj文件所在目录上

5、执行dotnet命令发布

dotnet publish -c Release -r linux-x64 --self-contained /p:PublishAot=true

.NET9 AOT部署的更多相关文章

  1. JIT和AOT编译详解

    JIT和AOT编译介绍 JIT - Just-In-Time             实时编译,即时编译 通常所说的JIT的优势是Profile-Based Optimization,也就是边跑边优化 ...

  2. 关于.net core程序的部署

    最近发布.net core程序的时候,发现它是可以独立部署的,它支持如下两种部署方式: 依赖框架的部署FDD.只发布我们的程序,运行前用户需要手动安装.net core runtime. 独立部署SC ...

  3. angular2的编译模式之AOT和JIT

    原文 https://www.jianshu.com/p/c959d90e91ce 大纲 1.angular应用为什么需要编译 2.angular的编译模式类型 3.JIT(Just-In-Time) ...

  4. .NET Core 3.0 构建和部署

    Default Executables 默认可执行文件 在 dotnet build 或 dotnet publish 期间,将创建一个与你使用的 SDK 的环境和平台相匹配的可执行文件. 和其他本机 ...

  5. ZKWeb 官网与演示站点的部署步骤 (Linux + Nginx + Certbot)

    因为没有给域名续费,加上私人时间不足,ZKWeb 的官网和演示站点已经停止了几个月的时间. 最近时间开始变多,所以重新购买了别的域名和服务器把官网和演示站点重新部署上去. 在此前站点是托管在共享主机上 ...

  6. Dart的JIT 与 AOT

    JIT:Just In Time AOT:Ahead of Time 含义: 目前,程序主要有两种运行方式:静态编译与动态解释. 静态编译的程序在执行前全部被翻译为机器码,通常将这种类型称为AOT ( ...

  7. 快速搞懂.NET 5/.NET Core应用程序的发布部署

    .NET Framework时代,.NET 应用程序大多直接部署运行在Windows服务器上,当然也可以通过Mono部署运行在Linux上.无论部署exe,还是IIS站点.或是Windows Serv ...

  8. 部署Angular应用到Github pages

    https://jeneser.github.io/blog/2017/08/08/angular-deploying-app-github-pages/ Published: August 08, ...

  9. .NET 7 的 AOT 到底能不能扛反编译?

    一:背景 1.讲故事 在B站,公众号上发了一篇 AOT 的文章后,没想到反响还是挺大的,都称赞这个东西能抗反编译,可以让破解难度极大提高,可能有很多朋友对逆向不了解,以为用 ILSpy,Reflect ...

  10. 【.NET 8】ASP.NET Core计划 - 支持更完善的AOT发布

    .NET7.0刚发布不久,.NET社区开始了.NET8.0的开发,重心重新回到了新功能的迭代. 我们知道在.NET7.0中一个令人激动的特新就是支持了NativeAOT,我们可以通过NativeAOT ...

随机推荐

  1. PHP无法连接MySQL8.0数据库问题处理 报错如下: SQLSTATE[HY000]

    PHP无法连接MySQL8.0数据库问题处理报错如下:SQLSTATE[HY000] [2054] The server requested authentication method unknown ...

  2. Java Study For Six Day( 面向对象二)

    static(静态)关键字 用于修饰成员(成员变量和成员函数) 被修饰后的成员具备以下的特点 随着类的加载而加载 优先于对象存在 被所有的对象共享 可以被类名直接调用 静态注意事项 静态方法只能访问静 ...

  3. linux下的rpm与yum

    一.源代码形式 1.      绝大多数开源软件都是直接以原码形式发布的 2.      源代码一般会被打成.tar.gz的归档压缩文件 3.      源代码需要编译成为二进制形式之后才能够运行使用 ...

  4. 【java基础】-- java接口和抽象类的异同分析

    在java中,通常初学者搞不懂接口与抽象类,这也是面试比较容易问到的一个问题.下面我来谈谈自己的理解.如有不妥之处,还望批评指正,不胜感激. 目录 1.抽象类怎么定义和继承? 2.接口怎么定义和实现? ...

  5. simpleui

    目录 一.simpleui 1.1 使用步骤 1.2 功能介绍 1.3 展示大屏 一.simpleui 之前公司里,做项目前后端结合,要使用权限,要快速搭建后台管理,使用djagno的admin直接搭 ...

  6. 【前端】【JavaScript】通过成绩判断等级

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 【前端】白天/黑夜主题切换:JS读取XML预设主题实现黑白主题切换

    上扩展实现多主题选择,切换主题) 先看一下XML文档 id值不能重复,一套主题的name要相同,亮色type1,暗色type0 <?xml version="1.0" enc ...

  8. LocalDateTime 简述

    Java 8 更新的部分内容中,有一部分代替了以往比较难用的 java.util.Date 类,并且创建了一套新的时间类型,该类型为: java.time.LocalDateTime. LocalDa ...

  9. Qt编写视频监控系统73-不同视频流不同类型的判断和解析(http/m3u8/rtsp/rtmp等)

    一.前言 这套视频监控系统大概从2018年起步整体框架,一步步积累到现在,中间经历了无数次的各种视频文件.视频流.视频设备的播放测试,比如光视频文件就有mp4/wmv/rmvb/mkv/avi等格式, ...

  10. Qt数据库应用14-超级自定义委托

    一.前言 在QTableView.QTreeView以及对于衍生的QTableWidget.QTreeWidget类中,需要用到自定义委托的情形很多,比如提供下拉框选择,进度条展示下载进度啥的,默认的 ...