네이티브 AOT 컴파일
.NET 프로젝트에서 Native AOT를 활성화하고 트리밍 분석을 이해하며 자체 포함 네이티브 바이너리를 게시합니다.
네이티브 AOT 컴파일은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
네이티브 AOT란 무엇인가
네이티브 사전 컴파일(AOT)은 게시 시점에 .NET 앱을 자체 포함형 네이티브 바이너리로 컴파일합니다. JIT 컴파일러도 대상에 필요한 .NET 런타임도 없으며 단일 실행 파일만 있으면 됩니다.
네이티브 AOT를 사용하는 경우
네이티브 AOT는 시작 시간과 메모리 사용량이 중요한 마이크로서비스, CLI 도구, 서버리스 함수에 적합합니다. 실행 중 리플렉션에 크게 의존하는 앱에는 적합하지 않습니다.
// Ideal use cases:
// - Serverless functions (AWS Lambda, Azure Functions)
// - High-throughput microservices (fast cold start)
// - CLI tools shipped as single-file executables
// - IoT / embedded scenarios
// Poor fit:
// - Apps using extensive reflection (e.g., dynamic proxies)
// - Apps loading plugins at runtime
// - Apps depending on libraries that don't support trimming
// Key benefits:
// - Sub-10ms startup time (vs 200-500ms for JIT)
// - Lower memory at startup (no JIT overhead)
// - Smaller attack surface (no JIT engine)네이티브 AOT로 게시하기
프로젝트 파일에서 AOT를 활성화하고 dotnet publish로 게시합니다. 출력 결과는 런타임 종속성이 없는 단일 네이티브 실행 파일입니다.
// .csproj:
<PropertyGroup>
<PublishAot>true</PublishAot>
<!-- Optional: disable invariant globalization for smaller binary -->
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
// Publish for Linux x64:
dotnet publish -r linux-x64 -c Release
// Publish for Windows x64:
dotnet publish -r win-x64 -c Release
// Output: bin/Release/net9.0/linux-x64/publish/MyApp
// Single executable, no dotnet runtime required네이티브 AOT를 사용하는 Minimal API
ASP.NET Core Minimal API는 .NET 8 이상에서 네이티브 AOT를 완전히 지원합니다. 미리 구성된 시작점으로 dotnet new webapiaot 템플릿을 사용합니다.
// dotnet new webapiaot -n FastApi
// Program.cs generated template:
var builder = WebApplication.CreateSlimBuilder(args); // AOT-optimized
// Must register serialization context for AOT:
builder.Services.ConfigureHttpJsonOptions(opts =>
opts.SerializerOptions.TypeInfoResolverChain.Insert(0,
AppJsonSerializerContext.Default));
var app = builder.Build();
app.MapGet("/hello", () => new Message("Hello, Native AOT!"));
app.Run();
record Message(string Text);
[JsonSerializable(typeof(Message))]
internal partial class AppJsonSerializerContext : JsonSerializerContext { }소스 생성 JSON 직렬화
네이티브 AOT에서는 리플렉션 기반 JSON 직렬화를 사용할 수 없습니다. 컴파일 시점에 직렬화 코드를 생성하려면 System.Text.Json 소스 생성을 사용해야 합니다.
// Define types to serialize:
public record Product(int Id, string Name, decimal Price);
public record OrderDto(int OrderId, List<Product> Items);
// Create a JsonSerializerContext for AOT:
[JsonSerializable(typeof(Product))]
[JsonSerializable(typeof(OrderDto))]
[JsonSerializable(typeof(List<Product>))]
internal partial class MyJsonContext : JsonSerializerContext { }
// Serialize / deserialize without reflection:
var json = JsonSerializer.Serialize(product, MyJsonContext.Default.Product);
var product = JsonSerializer.Deserialize(json, MyJsonContext.Default.Product);트리밍 경고
네이티브 AOT로 게시하면 기본적으로 트리밍이 활성화됩니다. 컴파일러는 사용하지 않는 코드가 제거된 후 실패할 수 있는 코드를 감지하면 경고를 표시합니다. CI에서는 트리밍 경고를 오류로 처리하십시오.
// .csproj: treat warnings as errors in CI
<PropertyGroup>
<PublishAot>true</PublishAot>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<TrimmerRootDescriptor>TrimmerRoots.xml</TrimmerRootDescriptor>
</PropertyGroup>
// Suppressing a specific warning when you know it is safe:
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(MyClass))]
public static void EnsureMyClassSurvivesTrimming() { }
// Or annotate parameters:
public static void Register(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
Type serviceType) { }AOT 호환성 분석기
개발 중에 AOT 호환성 분석기를 실행하여 게시 시점의 실패로 이어지기 전에 호환되지 않는 코드 경로를 발견하십시오.
// Enable analysis without actually publishing AOT:
<PropertyGroup>
<EnableAotAnalyzer>true</EnableAotAnalyzer>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
</PropertyGroup>
// Run:
// dotnet build
// => analyzer reports issues in build output
// Common warnings:
// IL2026: member uses RequiresUnreferencedCode
// IL2046: member annotated with RequiresUnreferencedCode derives from unannotated
// IL3050: member uses RequiresDynamicCode시작 성능 비교
네이티브 AOT는 JIT로 컴파일된 앱에 비해 시작 시간과 메모리 사용량을 크게 줄입니다. 일부 워크로드에서는 게시 시간이 더 길어지고 실행 파일 크기가 커지는 것이 절충점입니다.
// Typical Minimal API measurements:
// JIT (.NET 9, linux-x64):
// Startup time: ~180ms
// Memory (RSS): ~60 MB
// Publish time: ~5s
// Executable: self-contained ~80 MB
// Native AOT (.NET 9, linux-x64):
// Startup time: ~5ms (36x faster)
// Memory (RSS): ~20 MB (3x less)
// Publish time: ~30s (6x slower to build)
// Executable: ~10 MB (8x smaller)
// For AWS Lambda / Azure Container Apps:
// AOT cold start: <10ms vs JIT: 300-500ms = significant billing savings실전: AOT를 사용하는 Lambda 함수
최대 콜드 스타트 성능을 위해 공식 Amazon.Lambda.RuntimeSupport 패키지를 사용하는 네이티브 AOT Lambda 함수입니다.
// dotnet new lambda.NativeAOT
// .csproj:
// <PublishAot>true</PublishAot>
// <StripSymbols>true</StripSymbols>
public class Function
{
[JsonSerializable(typeof(APIGatewayProxyRequest))]
[JsonSerializable(typeof(APIGatewayProxyResponse))]
internal partial class LambdaContext : JsonSerializerContext { }
static async Task Main()
{
Func<APIGatewayProxyRequest, ILambdaContext, APIGatewayProxyResponse>
handler = FunctionHandler;
await LambdaBootstrapBuilder
.Create(handler, LambdaContext.Default.APIGatewayProxyRequest)
.Build()
.RunAsync();
}
static APIGatewayProxyResponse FunctionHandler(
APIGatewayProxyRequest req, ILambdaContext ctx)
=> new() { StatusCode = 200, Body = "{\"status\":\"ok\"}" };
}빠른 확인
네이티브 AOT에서 리플렉션 기반 직렬화 대신 System.Text.Json 소스 생성을 사용해야 하는 이유는 무엇입니까?
복습: 네이티브 AOT 컴파일
핵심 요점:
- 네이티브 AOT는 자체 포함 네이티브 바이너리로 컴파일되므로 런타임이 필요하지 않습니다
- 서버리스, 마이크로서비스 및 CLI 도구에 적합합니다(빠른 시작, 적은 메모리)
<PublishAot>true</PublishAot>로 활성화하고-r <rid>로 게시하십시오- System.Text.Json 소스 생성을 사용해야 하며 리플렉션 직렬화는 작동하지 않습니다
- 개발 중 호환성 문제를 발견하려면
EnableAotAnalyzer를 사용하십시오 - 절충점: 게시 시간이 더 길고 리플렉션이 제한되지만 콜드 스타트는 5~35배 빠릅니다
자주 묻는 질문
“네이티브 AOT 컴파일” 강의는 무료인가요?
네 — “네이티브 AOT 컴파일” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“네이티브 AOT 컴파일”에서 뭘 배우나요?
.NET 프로젝트에서 Native AOT를 활성화하고 트리밍 분석을 이해하며 자체 포함 네이티브 바이너리를 게시합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C# Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“네이티브 AOT 컴파일” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.