출처
: https://namu.wiki/w/안드로이드%20런타임
: http://118k.tistory.com/250
: http://gdgand.github.io/lollipop/2015/03/12/lollipop.html
참조 자료
: http://charlie0301.blogspot.kr/2014/02/dalvik-art.html
Dalvik 'JIT(Just in Time)' vs ART 'AOT (Ahead of Time)'
1. 배경
일반적인 컴파일 언어는 CPU의 아키텍쳐와 플랫폼의 환경에 맞추어 기계어로 컴파일된다.
간단히 말하자면, 사람이 작성한 프로그램을 CPU가 알아들을 수 있는 언어로 바로 번역하여 저장하는 것이다.
이 CPU간의 서로 다른 "언어"가 "아키텍쳐"에 해당한다고 보면 된다.
그러나, 자바의 경우는 기본적으로 한 가지 CPU의 아키텍쳐나 환경에 맞추는 것이 아닌 바이트코드라는 것으로 컴파일 되며,
이를 실행하기 위해서는 자바 가상 머신이 필요하다. 이렇게 하는 이유는 자바는 바이트코드 하나만으로
여러가지 아키텍쳐나 플랫폼에서 작동할 수 있도록 하는 것이 목표이기 때문이다.
아키텍쳐와 플랫폼에 맞는 가상머신만 있다면 하나의 실행 파일만 가지고도 각종 장치에서 쓸 수 있는 것이다.
플랫폼이 안 맞아서 작동시키지 못하는 예시가 안드로이드 <-> iOS 혹은 윈도우 <-> 맥 <-> 리눅스 간의 호환이 안 되는 경우이고,
아키텍쳐가 안 맞아서 작동시키지 못하는 예시가 윈도우 8 <->윈도우 8 RT 간의 호환이 안되는 경우이다.
안드로이드도 Java 언어를 사용하기 때문에 VM이 필수적이다. 이에 자바 가상머신(JVM)을 사용할 수 있지만,
JVM은 라이선스 문제가 있어서 구글에서는 Dalvik VM을 따로 개발해서 안드로이드에 넣었다.
2. 안드로이드 버전별 역사
안드로이드 2.2 프로요 버전 이전의 달빅 VM에서는, 앱이 구동되는 와중에 실시간으로 자바 코드를 CPU에 맞게 변환하였다.
안드로이드 2.2 프로요 버전 이후의 달빅 VM에서는, JIT 컴파일러가 추가되어 앱 최초 실행시에 자바 코드가 일정 부분 한꺼번에
변환이 되며, 변환된 내용을 램 상에 올려 놓고 작업하게 된다.
안드로이드 5.0 롤리팝 버전 이후의 ART VM에서는, AOT 컴파일러가 기본으로 적용되어 프로그램 최초 실행시가 아닌,
그 이전에(주로 설치시에) 한번에 전체를 변환해 두고 저장한 뒤, 프로그램 실행시 마다 변환된 코드를 읽어들이게 된다.
안드로이드 누가 이후의 ART VM에서는, JIT와 AOT를 모두 탑재함으로써 최초 설치시에는 무조건 JIT를 사용하도록 하여
설치시간과 용량을 적게 소모하도록 한 뒤, 차후 상황에 따라 각 방식을 유연하게 적용하도록 하였다.
3. 상세
JIT(Just-In-Time) 컴파일러 이전에는, 앱이 구동되는 와중에 실시간으로 자바 코드를 CPU에 맞게 변환하였다.
그러나 JIT 컴파일러가 들어가고부터는 앱 최초 실행시에 자바 코드가 일정 부분 한꺼번에 변환이 되어,
변환된 내용을 램 상에 올려 놓고 작업하게 된다.
이러한 JIT 컴파일러가 추가되면서 성능은 향상되었다. 그런데 여기서 문제가 생겼다.
JIT 컴파일러가 돌아가는데 실행시마다 하드웨어 전체적으로 상당한 부하가 생겨
배터리 시간이 안습이 되버리는 불상사가 터진 것. 화면 전환이 많을수록 배터리는 더욱 더 안습이 되어버렸다.
게다가 달빅은 실행 직전에 실행 부분 전체를 RAM에다가 올려놔야 하기 때문에 각 앱이 다른 OS보다 램을 처묵처묵하는 양이
더 많아 램고자라고도 알려져 있다.
이 때문에 안드로이드는 한 때 iOS와 많이 비교되면서 가루가 되도록 까이게 되는 원인이 되어버렸다.
또한, 안드로이드에 프로세서 킬러를 함부로 쓰면 안 된다는 말도 여기에서 나온 것.
이런 문제를 해결하기 위해서 구글에서 새로 개발해낸 것이 ART로, AOT 컴파일러를 기반으로 제작되었다.
앞에서 살펴본 바와 같이, JIT 컴파일러는 프로그램 최초 실행시마다 코드를 변환한다.
반면, AOT 컴파일러는 프로그램 최초 실행시가 아닌, 그 이전에(주로 설치시에) 한번에 전체를 변환해두고 저장한 뒤,
프로그램 실행시 마다 변환된 코드를 읽어들이게 된다.
4. 왜 이런 구조를 쓰고 있었나?
AOT 컴파일러가 적용된다면 당연히 압도적인 속도 개선을 기대할 수 있으며,
새로운 플랫폼으로써의 안정성만 보장된다면 앱이 동작하는 안드로이드 플랫폼 자체가 발적화 소리를 들을 일은 사실상 없게 될 것이다.
물론 앱 개발자가 허접이면 얄짤없지만 그건 어느 플랫폼이나 마찬가지고.
안드로이드 4.4 킷캣이 실행 중인 안드로이드 기기에서 런타임을 ART로 설정해 놓으면,
앱이 설치 될 때 앱에 들어 있는 중간 언어를 모조리 번역을 미리 해 놓는다.
그 덕분에 기존의 JAVA 기반 앱 플랫폼으로써의 문제점들은 모두 사라지고, 네이티브 언어와 동급의 성능을 체감할 수 있게 되었다.
5. 단점
AOT 컴파일러도 단점은 있다.
앱을 설치하면 공간을 1.5배에서 2배 가량을 더 많이 차지하고, 설치 속도가 달빅VM보다 더 느리다는 것.
이는 JIT없는 초창기 달빅 머신은 모든 명령어를 실행마다 한줄한줄, JIT는 매번 어플을 실행할 때마다
필요한 부분을 컴파일 하는 반면에, ART의 AOT 컴파일러는 처음 인스톨 할 때 필요한 컴파일 작업을 다 해놓기 때문에
생기는 근본적인 한계이다.
또한 킷캣까지 대부분의 앱은 런타임을 모두 달빅에 초점을 잡아 개발했기 때문에 달빅VM에서 잘 돌아가던 앱들이
ART 환경에서는 안 돌아가는 호환성 문제가 발생한다.
그리고, 킷캣~롤리팝 초기(5.0) 기준으로 ART는 아직 적용 초기 단계인지라 사용자도 구글도 밝혀내지 못한 잠재적인 문제들이
산재해 있을 가능성이 있다.
다만 15년말 현재는 이미 5.1.1을 넘어 마시멜로와 안드로이드 N(7.0)을 향해 가고 있는 만큼 이러한 미검증의 문제는 초기에 비해
적어졌다고 할 수 있다.
* 구글 I/O 2016의 발표에 따른 추가 사항
안드로이드 N 에서는 ART 에 JIT 컴파일러도 추가된다고 합니다.
프로필 가이드 방식의 JIT/AOT 컴파일
Android N에서 코드 프로파일링을 포함한 JIT(Just in Time) 컴파일러를 ART에 추가했으며, 실행 시에 Android 앱의 성능이 계속해서 향상됩니다.
JIT 컴파일러는 ART의 현재 AOT(Ahead of Time) 컴파일러를 보완하고 런타임 성능을 개선하며, 저장 공간을 절약하고,
앱 업데이트 및 시스템 업데이트 속도를 빠르게 해줍니다.
프로필 가이드 방식의 컴파일을 통해 ART는 실제 사용량과 기기의 조건에 따라 각 앱의 AOT/JIT 컴파일을 관리할 수 있습니다.
예를 들어, ART는 최적의 성능을 위해 각 앱의 핫 메서드에 대한 프로필을 유지관리하고 이들 메서드를 프리컴파일하고 캐싱할 수 있습니다.
이 경우 앱의 다른 부분들은 실제로 사용될 때까지 컴파일하지 않고 남겨둡니다.
프로필 가이드 방식의 컴파일은 앱의 주요 부분들에서 성능을 개선할 뿐만 아니라 관련 바이너리를 비롯한 앱 전체의 RAM 공간을 줄이는 데 도움이 됩니다.
이 기능은 저용량 메모리 기기에 특히 중요합니다.
ART는 기기 배터리에 미치는 영향이 최소화되는 방식으로 프로필 가이드 방식의 컴파일을 관리합니다.
ART는 기기가 유휴 상태이고 충전 중일 때만 프리컴파일을 수행하며, 해당 작업을 미리 수행하여 시간과 배터리를 절약합니다
https://developer.android.com/preview/api-overview.html#jit_aot
런타임 엔진 ART
초기 안드로이드에 탑재된 가상 머신 달빅(Dalvik)은 모바일 환경을 고려해 적은 메모리, 최적화된 리소스 관리,
최소화 오버헤드 등이 목표였다. 자주 수행되는 구간(트레이스, trace)을 기계어 코드로 바꾸는 JIT(Just-in-time) 컴파일러는
안드로이드 프로요(2.2) 버전에서야 도입됐다. 달빅의 기본 전략은 달빅 바이트코드(Dalvik bytecode)로 된 코드를 한 줄씩
해석하고 반복 수행되는 구간을 기계어 코드로 변환해 효율을 높이는 것이었다.
트레이스라 불리는 특정 구간을 번역하는 작업은 메소드 단위로 기계어로 변환하는 것보다 시간이 짧게 소요됐다.
또 변환된 기계어 코드의 용량이 작아 메모리가 적고 CPU 파워가 낮은 상황에 적합했다.
그러나 경량 가상 머신에서 시작한 달빅은 고성능과 고기능에서 구조적 한계를 드러냈다.
구글은 안드로이드 킷캣부터 ART(Android Runtime)를 준비했고 롤리팝부터는 강제 사항이 됐다.
ART는 AOT(ahead-of-time) 방식의 런타임 환경이다. ART의 내장된 dex2oat 유틸리티는 달빅에서 쓰이던 달빅 바이트 코드와
리소스 파일이 통합된 .dex 파일을 리눅스에서 널리 쓰이는 실행파일 형태 ELF(Executable and Linkable Format)로 변환한다.
dex2oat는 앱의 초기 수행 시 호출되며 ART의 AOT는 앱의 최초 수행 과정에 dex2oat 유틸리티를 이용, 실행 파일을 얻어내는
기술인 셈이다.
이로 인해 롤리팝은 수행 성능, 가비지 컬렉션(GC : Garbage collection)의 성능, 프로파일링, 디버깅 등에서 이점을 얻었다.
<그림 5> 달빅과 ART의 차이.
달빅은 DEX 파일에서 최적화된 Odex를 얻고 ART는 실행파일 ELF를 얻는다.
새로운 방식이 적용됐기 때문에 앱에 따라 문제가 발생할 수 있다.
AOT와 과련해서는 안드로이드 플랫폼과 관련된 이슈가 많기 때문에 안드로이드 이슈 리스트를 참조하며 문제를 해결하자.
'IT_Programming > Android_Java' 카테고리의 다른 글
[펌_번역] VectorDrawable 대응 정리 (0) | 2016.08.11 |
---|---|
[펌] Android N - 멀티윈도우 지원 (0) | 2016.08.04 |
[안드로이드] CoordinatorLayout 활용 (Scrolling Techniques) (0) | 2016.07.28 |
[펌][Android_Studio] Debug모드에서 Break Point 활용하여 Log를 찍어보자 (0) | 2016.07.18 |
[DEVIEW 2013] WebView 뛰어 넘기 – 고성능 WebView 만들기 (0) | 2016.07.14 |