AOT

프로그램을 실행하기 전에 미리 네이티브 기계어로 컴파일하는 방식입니다.

AOT vs JIT 핵심 비교

[ AOT (Ahead-Of-Time) ]
소스코드 → 컴파일러 → 네이티브 기계어 → 실행
           ↑ 실행 전에 완료              ↑ CPU가 바로 실행

[ JIT (Just-In-Time) ]
소스코드 → 컴파일러 → 바이트코드 → VM 실행 중 → 핫스팟을 기계어로 변환
                                   ↑ 실행 중에 컴파일 발생
항목AOTJIT
변환 시점실행 전실행 중
결과물네이티브 바이너리바이트코드 + 런타임 변환
시작 속도빠름 (이미 기계어)느림 (워밍업 필요)
장기 실행 성능일정워밍업 후 더 빠를 수 있음
VM 필요 여부불필요필요 (JVM, CLR 등)

언어별 AOT 적용 현황

원래부터 AOT인 언어

C     → gcc     → 기계어 바이너리
C++   → g++     → 기계어 바이너리
Rust  → rustc   → 기계어 바이너리
Go    → go build → 기계어 바이너리

이 언어들은 태생부터 AOT 컴파일이 기본입니다.

AOT를 선택할 수 있는 언어

언어기본 방식AOT 도구
JavaJVM (JIT)GraalVM Native Image
KotlinJVM (JIT)Kotlin/Native, GraalVM
C#.NET CLR (JIT).NET Native AOT
DartDart VM (JIT)dart compile exe
JavaScriptV8 (JIT)Snapshot (제한적 AOT)

JIT만 사용할 때의 문제

클라이언트 요청 → 서버리스 함수 시작
                    │
                    ▼
              JVM 초기화 (~500ms)
              클래스 로딩 (~300ms)
              Interpreter 실행
              JIT 워밍업 (~1000ms)
                    │
                    ▼
              실제 응답 ← 이미 2초 가까이 지남 (콜드 스타트)

이 콜드 스타트 문제가 AOT의 핵심 동기입니다.

AOT 적용 시

클라이언트 요청 → 서버리스 함수 시작
                    │
                    ▼
              네이티브 바이너리 즉시 실행 (~50ms)
                    │
                    ▼
              실제 응답 ← 거의 즉시

AOT의 장단점

장점상세
즉시 시작JVM 초기화·JIT 워밍업 없이 바로 실행
낮은 메모리JVM 자체의 메모리 오버헤드 없음
배포 간편단일 바이너리, 런타임 설치 불필요
예측 가능한 성능처음부터 끝까지 일정한 속도
단점상세
런타임 최적화 부재프로파일링 기반 최적화가 없어 장기 실행 시 JIT보다 느릴 수 있음
리플렉션 제한동적으로 클래스를 탐색하는 기능에 별도 설정 필요
빌드 시간 증가AOT 컴파일 자체가 오래 걸림 (수 분 이상)
플랫폼 종속OS·CPU마다 별도 빌드 필요 ("Write Once, Run Anywhere" 상실)
바이너리 크기필요한 라이브러리가 바이너리에 포함되어 커질 수 있음

AOT가 JIT보다 느릴 수 있는 이유

[ AOT ]
컴파일 시점에 알 수 있는 정보만으로 최적화
→ "이 분기는 보통 true일 것이다" 같은 런타임 정보 없음

[ JIT ]
실행 중 프로파일링 데이터 수집
→ "이 메서드는 99% String 타입으로 호출된다"
→ 해당 케이스에 특화된 기계어 생성 (Speculative Optimization)
성능
 ▲
 │          ┌─── JIT (워밍업 후 최적화)
 │         ╱
 │        ╱
 │  ─────╱────── AOT (일정한 성능)
 │  ╱
 │ ╱ ← JIT 워밍업 구간
 └──────────────────────────────► 시간

실무 선택 기준

상황추천이유
AWS Lambda, Cloud FunctionsAOT콜드 스타트 최소화
CLI 도구AOT즉시 시작, 단일 바이너리 배포
컨테이너 마이크로서비스AOT이미지 경량화, 빠른 스케일 아웃
대규모 장기 운영 서버JITJIT 최적화로 최대 처리량
개발·디버깅 단계JIT빠른 빌드, JVM 디버깅 도구 활용

핵심 정리

AOT는 실행 전에 미리 기계어로 컴파일하는 방식으로, C/C++/Rust/Go는 태생부터 AOT이고, Java/Kotlin/C#은 GraalVM 등을 통해 선택적으로 AOT를 적용할 수 있습니다. 빠른 시작과 낮은 메모리가 강점이지만, 런타임 최적화 부재와 플랫폼 종속성이 트레이드오프입니다. 결국 AOT와 JIT는 우열이 아니라 실행 환경에 따른 선택의 문제입니다.

CSLOG에서 보기