.NET Native AOT는 실행 속도와 메모리 효율성 면에서 큰 이점을 제공하지만, **모든 코드가 빌드 시점에 확정되어야 한다는 정적 분석(Static Analysis)**의 특성상 다음과 같은 주요 제약 사항이 발생합니다.
1. 런타임 동적 기능 및 리플렉션 제약
- 동적 코드 생성 불가: System.Reflection.Emit과 같은 런타임 시점의 IL 코드 생성 및 실행을 전혀 지원하지 않습니다.
- 동적 로딩 불가: Assembly.LoadFile이나 Assembly.LoadFrom과 같이 실행 중에 어셈블리를 동적으로 불러오는 기능이 제한됩니다.
- 리플렉션 트리밍 문제: 정적 분석기는 실제 호출되지 않는 코드를 제거(Trimming)하는데, 문자열 기반의 리플렉션으로 타입을 호출하면 분석기가 이를 감지하지 못해 필요한 타입이 삭제되어 런타임 오류(TypeLoadException)가 발생할 수 있습니다.
2. 제네릭 및 타입 인스턴스화 제한
- 런타임 제네릭 생성 불가: 실행 중에 MakeGenericType을 사용하여 새로운 제네릭 형상을 만드는 것은 AOT 컴파일러가 빌드 시점에 모든 조합을 예측할 수 없으므로 실패할 가능성이 큽니다.
- 바이너리 크기 증가: 제네릭 매개변수에 구조체(struct) 타입을 사용할 경우, AOT는 모든 조합에 대해 별도의 네이티브 코드를 미리 생성해야 하므로 결과물 파일의 크기가 급격히 커질 수 있습니다.
3. 라이브러리 및 환경 호환성
- 미지원 기술: C++/CLI 및 Windows의 기본 내장 COM 기능을 사용할 수 없습니다.
- 정적 라이브러리 링크 제한: .NET Native AOT를 정적 라이브러리(.lib, .a)로 빌드할 경우, 가비지 컬렉터(GC) 및 런타임 심볼 충돌로 인해 한 애플리케이션에 오직 하나의 닷넷 정적 라이브러리만 포함할 수 있습니다.
- 3rd-party 라이브러리: 리플렉션에 의존하는 기존의 많은 라이브러리나 프레임워크가 AOT 환경에서 정상적으로 작동하지 않을 수 있습니다.
4. 성능 및 기타 특성
- LINQ 식 트리(Expressions): 런타임 컴파일이 불가능하므로 항상 인터프리터 형태로 실행되며, 이는 JIT 방식보다 속도가 느립니다.
- 빌드 시간: 모든 코드를 기계어로 직접 번역하고 최적화하는 과정이 복잡하여 게시(Publish) 시간이 일반 빌드보다 상당히 길어집니다.
- 플랫폼 종속성: 빌드 시 특정 OS 및 CPU 아키텍처(예: Linux x64)를 지정해야 하며, 해당 환경과 호환되는 실행 파일만 생성됩니다.
요약하자면: Native AOT는 마치 **"인쇄가 완료된 책"**과 같습니다. 이미 모든 내용이 활자로 고정되어 있어 읽기(실행)는 매우 빠르지만, 책을 읽는 도중에 내용을 수정하거나 새로운 페이지를 끼워 넣는(동적 코드 생성 및 로딩) 등의 유연한 변화는 허용되지 않는 것과 같습니다.





