[안드로이드] apk 빌드 과정 (+ DVM,ART)
Apk 빌드 과정
1. 안드로이드의 리소스 파일들을 코드레벨에서 구분하기 위해서 aapt는 R.java를 만든다.
2. R.java와 작성한 코드들 그리고 aidl에 의해서 만들어진 자바 인터페이스들은 자바 또는 코틀린 컴파일러에 의해서 클래스파일로 컴파일된다.
3. 클래스 파일들과 3rd party 라이브러리들은 그 후 art 가상머신에서 실행하기 위해서 dex파일로 만들어진다.
4. dex파일은 컴파일된 리소소들, 다른 리소스들이 합쳐져서 apk가 만들어지는데 해당 apk를 키스토어로 서명한다.
5. 또 이 apk를 적은 메모리를 사용할 수 있게 하는 zipalign을 통해 최종 apk를 만들어낸다.
*zipalign: 보관 파일 중 압축되지 않은 모든 파일이 파일 시작 부분을 기준으로 정렬되도록 하는 ZIP 파일 정렬 도구입니다. 이렇게 하면 mmap(2)를 통해 이러한 파일에 직접 액세스 할 수 있으므로 RAM에 데이터를 복사할 필요가 없고 앱 메모리 사용량을 줄일 수 있습니다.
*dex : dex tool에 의해서 여러 클래스들을 압축한 dex파일로 리컴파일 된다. 자바 바이트코드는 dvm, art에서도 사용할 수 있는 달빅 바이트코드로 변환이 필요하다. 달빅 바이트 코드는 dex파일에 포함된다. Jvm은 스택 기반으로 명령어들을 처리했고 dvm은 레지스터 기반으로 명령어를 처리하기 때문에 서로 바이트 코트가 차이가 나서 달빅 바이트 코드로 변환해주는 작업은 필요하다.
안드로이드 가상머신의 변화 과정
1) JVM -> DVM (dalvik)
안드로이드는 모바일 기기에 특화된 배터리 수명과 메모리를 효율적으로 사용하기 위한 가상머신이 필요했다.
dvm은 기존 스택 기반 모델에서 레지스터 기반 모델로 변경되었다. 스택 기반 모델에 비해서 레지스터 기반 모델은 실행 속도가 빠르고 메모리를 덜 차지하기 때문에 비교적 효율적이다. dvm을 실행할 때 apk의 dex파일을 그대로 사용하는 게 아니라 odex(최적화된 dex파일)을 사용한다.
단점은 DVM은 jit 방식을 사용해서 실행이 될 때 기계어로 바로 해석을 하고 반복적으로 사용되는 기계어들은 메모리에 저장해 놓는다. 그렇기 때문에 메모리를 많이 차지하고 실행 속도가 느리다. 그리고 컴파일 타임에 에러를 발견하지 못한다.
2) DVM -> ART (android runtime)
DVM의 단점인 메모리를 많이 차지하고 실행 속도가 느린 점을 해결하기 위해 ART가 나왔다. ART는 JIT방식이 아닌 AOT 방식을 사용하는데 AOT 방식은 APK가 설치될 때 한 번에 모두 기계어로 해석을 해놓고 해당 기계어를 사용한다. apk의 dex파일을 그대로 사용하는 것이 아니고 dex파일을 dex2 oat 툴로 dex-> odex ->
Oat 파일로 변환한다. Oat는 elf 파일 형식 (cpu가 실행 가능한 파일)으로 변환되어서 실행된다.
단점은 실행 속도는 빠른 반면 설치 시간과 용량이 커진다.
킷캣부터 ART가 준비되었고 롤리팝(API 21)부터 강제되었다. 초창기에 달빅에서 실행되던 앱들이 ART환경에서 죽는 현상이 발생했었다.
그 후, 누가(API 24) JIT 방식과 AOT방식을 섞어서 사용하게 되었다. 최초 설치 시에는 JIT방식, 잠깐씩 필요한 부분을 기계어로 변화해 놓는다.
Reference.
https://medium.com/mj-studio/안드로이드-어디까지-아세요-1-build-process-df6a69f73337
안드로이드, 어디까지 아세요 [1] - Build process
APK bundling, Proguard, R8, D8, Desugaring …
medium.com
https://developer.android.com/studio/command-line/zipalign?hl=ko
zipalign | Android 개발자 | Android Developers
zipalign은 Android 애플리케이션 파일에 중요한 최적화 기능을 제공하는 보관 파일 정렬 도구입니다.
developer.android.com