.NET Native AOT 入門【JIT/ReadyToRun/trimmingとの違い】
Native AOT とは
Native AOT は、.NET アプリを publish 時にネイティブコードへ事前コンパイル する発行モデルです。普段の .NET は実行時に JIT(Just-In-Time コンパイル)でネイティブコードを生成しますが、Native AOT はその作業を publish 時に済ませてしまいます。
ひとことで言うと「動的な世界を少し捨てて、静的に固めやすい世界へ寄せる」仕組みです。
ReadyToRun との違い
| 観点 | 通常の JIT | ReadyToRun | Native AOT |
|---|---|---|---|
| 実行時 JIT | 使う | まだ使う | 使わない |
| 配布物 | IL 中心 | IL + 事前生成コード | ネイティブ実行ファイル中心 |
| 起動速度 | 基準 | 改善 | さらに改善 |
| 互換性 | 広い | 比較的広い | 制約が強い |
ReadyToRun は JIT の仕事を少し前倒しする方向。Native AOT は JIT を前提にしない方向です。
Native AOT のメリット
- 起動が速い: CLI ツールや短命プロセスで JIT の重さがなくなる
- 配布が楽: .NET Runtime の事前インストールが不要。コンテナイメージも軽量に
- 実行環境の前提が減る: JIT 不要なので制約のある環境でも動かしやすい
Native AOT の制約
- リフレクションが厳しい:
Assembly.LoadFile、System.Reflection.Emit、実行時の型検索などが動かない - 動的コード生成が使えない
- trimming との深い結びつき: 依存ライブラリの書き方にも影響される
- Windows デスクトップに注意: WPF / WinForms は相性が悪い。built-in COM もない
向いているケース
- 起動が大事な CLI ツール
- worker / 小さな Web API
- ネイティブ連携の責務が狭い部品
- コンテナの小さなサービス
向いていないケース
- WPF / WinForms の既存大規模アプリ
- plugin 読み込みが主役の構成
- COM 依存の強い構成
- リフレクションベースのシリアライザーや DI を多用する場合
最小手順
csproj に以下を追加:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
発行コマンド(Windows x64 の場合):
dotnet publish -c Release -r win-x64
Linux x64 の場合:
dotnet publish -c Release -r linux-x64
JSON シリアライズの注意
System.Text.Json を使う場合は source generation を使うこと:
[JsonSerializable(typeof(AppConfig))]
internal partial class AppJsonContext : JsonSerializerContext { }
string json = JsonSerializer.Serialize(config, AppJsonContext.Default.AppConfig);
まとめ
- Native AOT は起動と配布に強いが、動的な仕組みに弱い
- 「全部の .NET アプリに付ける標準スイッチ」ではない
- 起動が大事、配布を軽くしたい、実行環境の前提を減らしたい場面で有効
- Windows デスクトップや COM が濃い世界では通常の .NET のほうが適切なことも多い
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
.NET Generic Host 入門
Generic Host が DI・設定・ログ・ライフタイム・BackgroundService をどう束ねるかを整理し、CreateApplicationBuilder と WebApplicationBuilder の関係、短命ジョブと常駐 worker の使い分けまで...
.NETの定期実行タイマー3種を使い分ける
PeriodicTimer・System.Threading.Timer・DispatcherTimer の違いと、async 処理・ThreadPool callback・WPF の UI 更新でどう使い分けるかを、判断表とコード例で整理した .NET 定期実行の入門記事です。
C#をNative AOTでDLL化しC/C++から呼び出す方法
C# のクラスライブラリを Native AOT でネイティブ DLL として発行し、UnmanagedCallersOnly で C/C++ から呼び出す構成を、設計指針・最小実装・はまりどころまでまとめて整理した実務向け解説記事です。
デスクトップアプリにGeneric Hostを導入する
WPF や WinForms の常駐アプリで、起動・停止・例外処理・定期処理が UI に染み出してきたら読みたい記事。Generic Host と BackgroundService を導入して責務を整理し、graceful shutdown まで設計に組み込む考え方を、最...
FileSystemWatcherの安全な使い方
FileSystemWatcher のイベントは完了通知ではないという前提に立ち、取りこぼし、重複通知、完了判定の落とし穴を整理し、再スキャン要求への畳み込み、原子的 claim、idempotency までの設計指針をまとめます。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
32bit / 64bit テーマ
32bit / 64bit、ネイティブ連携、C++/CLI まわりを整理するトピックです。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
Windowsアプリ開発
業務アプリ、装置連携、通信ツールなどの Windows ソフト開発を支援します。
技術相談・設計レビュー
改修方針、設計レビュー、既存資産の扱いを整理するための技術相談です。