
안드로이드 개발을 하다 보면 ART, Dalvik, DEX 같은 용어들을 자주 접하게 된다. 하지만 정작 이들이 어떤 역할을 하는지, 왜 중요한지 제대로 이해하지 못하는 경우가 많다. 오늘은 안드로이드 앱이 실행되는 핵심 메커니즘에 대해 정리해보려고 한다.
우리가 작성한 Java나 Kotlin 코드가 안드로이드에서 실행되려면 특별한 변환 과정이 필요하다. 이 과정을 담당하는 것이 바로 DEX 컴파일러다.
DEX(Dalvik Executable)는 안드로이드에 최적화된 바이트코드 형식이다. 일반적인 Java 컴파일 과정과 비교해보면:
안드로이드는 시대에 따라 다양한 DEX 컴파일러를 제공해왔다:
실제로 R8을 사용하면 앱 크기가 20-30% 정도 줄어드는 효과를 볼 수 있다. ProGuard를 따로 돌릴 필요도 없어서 빌드 시간도 단축된다.
Dalvik은 안드로이드 4.4(KitKat)까지 사용된 초기 런타임이다. 2008년 안드로이드가 처음 나왔을 때의 모바일 환경을 생각해보면 Dalvik의 설계 철학을 이해할 수 있다.
하지만 시간이 지나면서 Dalvik의 단점들이 명확해졌다:
안드로이드 5.0(Lollipop)부터 도입된 ART(Android Runtime)는 Dalvik의 한계를 극복하기 위해 설계되었다.
AOT(Ahead-Of-Time) 컴파일은 앱 설치 시점에 전체 DEX 코드를 네이티브 코드로 미리 변환한다. dex2oat라는 도구가 이 작업을 담당하며, 결과물은 .oat 파일(ELF 실행 파일)로 저장된다.
실제 개발하면서 체감할 수 있는 차이점들이다:
앱 시작 시간
런타임 성능
배터리 수명
안드로이드 7.0(Nougat)부터 ART는 AOT와 JIT를 함께 사용하는 하이브리드 방식으로 진화했다:
1. 설치 시: 최소한의 컴파일만 수행 (빠른 설치)
2. 실행 중: JIT로 핫 코드 감지
3. 유휴 시간: 프로파일 기반 AOT 컴파일 (배터리 충전 중)
이렇게 하면 설치 시간과 저장 공간, 실행 성능의 균형을 맞출 수 있다.
Dalvik에서 ART로의 전환은 안드로이드 성능 향상의 큰 전환점이었다. 개발자 입장에서는 특별히 신경 쓸 부분이 많지 않지만, 이러한 런타임의 동작 원리를 이해하면 더 나은 성능의 앱을 만드는 데 도움이 된다.
특히 앱 시작 시간이나 배터리 효율성이 중요한 프로젝트를 진행한다면, ART의 특성을 고려한 최적화 전략을 수립할 수 있을 것이다.