ART라는 이름의 과거에 존재했던 보이그룹에 대해서는 ART(음악 그룹) 문서를 참조하십시오.
아트의 한국어 뜻을 포함한 다른 의미에 대해서는 아트 문서를 참조하십시오.
목차
Android Runtime
1 개요
기존의 달빅VM의 한계점을 해결하기 위해서 구글에서 새로 개발한 런타임.
안드로이드 런타임(Android Runtime)을 줄여서 ART라고도 부른다. 성능이 예술적이라서 ART라 카더라
2016년 하반기에 출시될 예정인 안드로이드 누가부터, ART라고 해서 무조건 AOT인 것은 아니므로 구분하여 서술할 것
2 적용
안드로이드 5.0 롤리팝(Lolipop)부터는 달빅VM을 완전히 폐지하고 ART를 새로운 런타임으로 완전히 대체했다. 또한 위에 설명했듯이 ART가 라이브러리인 점때문에 x86, mips 아키텍처 및 64비트를 공식적으로 지원하게 되었다.[1][2]
3 JIT vs AOT
3.1 배경
일반적인 컴파일 언어는 CPU의 아키텍쳐와 플랫폼의 환경에 맞추어 기계어로 컴파일된다. 간단히 말하자면, 사람이 작성한 프로그램을 CPU가 알아들을 수 있는 언어로 바로 번역하여 저장하는 것이다. 이 CPU간의 서로 다른 "언어"가 "아키텍쳐"에 해당한다고 보면 된다. 그러나, 자바의 경우는 기본적으로 한 가지 CPU의 아키텍쳐나 환경에 맞추는 것이 아닌 바이트코드라는 것으로 컴파일 되며, 이를 실행하기 위해서는 자바 가상 머신이 필요하다. 이렇게 하는 이유는 자바는 바이트코드 하나만으로 여러 가지 아키텍쳐나 플랫폼에서 작동할 수 있도록 하는 것이 목표이기 때문이다. 아키텍쳐와 플랫폼에 맞는 가상머신만 있다면 하나의 실행 파일만 가지고도 각종 장치에서 쓸 수 있는 것이다. 플랫폼이 안 맞아서 작동시키지 못하는 예시가 안드로이드 <-> iOS 혹은 윈도우<->맥<->리눅스 간의 호환이 안 되는 경우이고, 아키텍쳐가 안 맞아서 작동시키지 못하는 예시가 윈도우 8 <->윈도우 8 RT 간의 호환이 안되는 경우이다.
안드로이드도 Java 언어를 사용하기 때문에 VM이 필수적이다. 이에 자바 가상머신(JVM)을 사용할 수 있지만, JVM은 라이선스 문제[3]가 있어서 구글에서는 Dalvik VM을 따로 개발해서 안드로이드에 넣었다.
3.2 안드로이드 버전별 역사
- 안드로이드 2.2 프로요 버전 이전의 달빅 VM에서는, 앱이 구동되는 와중에 실시간으로 자바 코드를 CPU에 맞게 변환하였다.
- 안드로이드 2.2 프로요 버전 이후의 달빅 VM에서는, JIT 컴파일러가 추가되어 앱 최초 실행시에 자바 코드가 일정 부분 한꺼번에 변환이 되며, 변환된 내용을 램 상에 올려 놓고 작업하게 된다.
- 안드로이드 5.0 롤리팝 버전 이후의 ART VM에서는, AOT 컴파일러가 기본으로 적용되어 프로그램 최초 실행시가 아닌, 그 이전에(주로 설치시에) 한번에 전체를 변환해 두고 저장한 뒤, 프로그램 실행시 마다 변환된 코드를 읽어들이게 된다.[4]
- 안드로이드 누가 이후의 ART VM에서는, JIT와 AOT를 모두 탑재함으로써 최초 설치시에는 무조건 JIT를 사용하도록 하여 설치시간과 용량을 적게 소모하도록 한 뒤, 차후 상황에 따라 각 방식을 유연하게 적용하도록 하였다.
3.3 상세
JIT(Just-In-Time) 컴파일러 이전에는, 앱이 구동되는 와중에 실시간으로 자바 코드를 CPU에 맞게 변환하였다. 그러나 JIT 컴파일러가 들어가고부터는 앱 최초 실행시에 자바 코드가 일정 부분 한꺼번에 변환이 되어, 변환된 내용을 램 상에 올려 놓고 작업하게 된다.
이러한 JIT 컴파일러가 추가되면서 성능은 향상되었다. 그런데 여기서 문제가 생겼다. JIT 컴파일러가 돌아가는데 실행시마다 하드웨어 전체적으로 상당한 부하가 생겨 배터리 시간이 안습이 되버리는 불상사가 터진 것. 화면 전환이 많을수록[5] 배터리는 더욱 더 안습이 되어버렸다. 게다가 달빅은 실행 직전에 실행 부분 전체를 RAM에다가 올려놔야 하기 때문에 각 앱이 다른 OS보다 램을 처묵처묵하는 양이 더 많아 램고자라고도 알려져 있다. 이 때문에 안드로이드는 한 때 iOS와 많이 비교되면서 가루가 되도록 까이게 되는 원인이 되어버렸다. 또한, 안드로이드에 프로세서 킬러를 함부로 쓰면 안 된다는 말도 여기에서 나온 것.
이런 문제를 해결하기 위해서 구글에서 새로 개발해낸 것이 ART로, AOT 컴파일러를 기반으로 제작되었다.
앞에서 살펴본 바와 같이, JIT 컴파일러는 프로그램 최초 실행시마다 코드를 변환한다. 반면, AOT 컴파일러는 프로그램 최초 실행시가 아닌, 그 이전에(주로 설치시에) 한번에 전체를 변환해 두고 저장한 뒤, 프로그램 실행시 마다 변환된 코드를 읽어들이게 된다.
비행 매뉴얼을 가지고 비유를 해 보자면, 기존의 컴파일 언어는 각국의 언어로 처음부터 인쇄되어 나오는 매뉴얼이라고 볼 수 있다. 자바 언어의 경우, 애초부터 배우기 쉬운 언어로 의도되어 만들어진 에스페란토어, 혹은 현실적으로는 세계 공용어 역할을 하는 영어 정도의 위치를 갖는다고 할 수 있겠다. JIT 이전에는 외국어 매뉴얼을 비행하는 도중에 계속 해석해 가면서 읽고 비행을 했다고 한다면, JIT는 비행 이전에 아 이번에 비행할 때에는 이런이런 부분을 쓰겠구나 하고 적당히 해석하면서 메모한 뒤 비행을 하는 것이고 AOT는 비행 메뉴얼을 받아오는 시점에서 완전히 번역해 놓고 번역본을 원본 매뉴얼과 함께 구비한 뒤에 번역본을 계속 읽으면서 비행하는 식이다. JIT는 책상 위가 항상 어지러울 것이고, AOT는 선반 위의 공간이 부족해지는 사태가 발생할 것이다. 직독직해할정도로 그 언어를 배우면 안 되느냐고는 묻지 말자
3.4 왜 이런 구조를 쓰고 있었나?
자바의 철학은 하드웨어 아키텍처에 영향을 받지 않는다는 것이다. ARM 프로세서에서 동작하는 네이티브 앱은 당연히 x86 프로세서 환경에서 동작하지 않아 코드를 재구축하는 과정이 필요하지만[6], 자바 앱이라면 이야기가 다르다. 앱과 하드웨어 사이에 중간 코드 및 가상 머신(VM)[7]이 끼어들기 때문에 하드웨어 플랫폼과 무관하게 구동이 가능하다.[8] 구글이 안드로이드를 만들 때 주목한 것이 이 부분이었다. 지금이야 ARM이 시장을 장악하기는 했지만 그 이전에는 MIPS도 어느 정도 시장 지분이 있는 상황이었고 예나 지금이나 데스크탑에 쓰이는 x86(64) 시장은 변함없이 강력하므로 잘만 하면 데스크탑 시장까지도 노릴 수 있는 것이다. 지금도 (비록 구글이 직접 나서서 하고 있는 것은 아니지만) Android-x86 프로젝트가 어느정도 활성화되어 있는 것에서 그 가능성을 엿볼 수 있다. 이런 이유로 자바를 선택한 뒤에, 어떻게 하면 그 구조를 조금이라도 효율적으로 써먹을 수 있을까 고심해 온 결과물이 JIT 컴파일이고 또 AOT 컴파일인 것이다.
다른 큰 이유는 일단 자바가 배우기 쉽고, 생산성이 높으며, 이미 자바 개발자가 차고 넘치는 데다가, 사용처도 굉장히 넓기 때문이라는 것도 있다. 자바 두 명 타요라는 개드립이 괜히 있는 게 아니다(...)[9] 상대적으로 후발주자였던 안드로이드가 앱 생태를 쉽게 구축할 수단으로써 자바를 선택했다는 것. 실제 자바의 구조로 인한 성능 저하 문제는 이미 제조 부문에서 뼈가 굵은 세계 유수 전자 제조사의 H/W 능력으로 어디까지나 어느 정도로는 커버가 가능한 상황이었다.[10]
3.5 성능 개선
AOT 컴파일러가 적용된다면 당연히 압도적인 속도 개선을 기대할 수 있으며, 새로운 플랫폼으로써의 안정성만 보장된다면 앱이 동작하는 안드로이드 플랫폼 자체가 발적화 소리를 들을 일은 사실상 없게 될 것이다.물론 앱 개발자가 허접이면 얄짤없지만 그건 어느 플랫폼이나 마찬가지고.
안드로이드 4.4 킷캣이 실행 중인 안드로이드 기기에서 런타임을 ART로 설정해 놓으면, 앱이 설치 될 때 앱에 들어 있는 중간 언어를 모조리 번역을 미리 해 놓는다.[11] 그 덕분에 기존의 JAVA 기반 앱 플랫폼으로써의 문제점들은 모두 사라지고, 네이티브 언어와 동급의 성능을 체감할 수 있게 되었다.
3.6 단점
AOT 컴파일러도 단점은 있다. 앱을 설치하면 공간을 1.5배에서 2배 가량을 더 많이 차지하고, 설치 속도가 달빅VM보다 더 느리다는 것. 이는 JIT없는 초창기 달빅 머신은 모든 명령어[12]를 실행마다 한줄한줄, JIT는 매번 어플을 실행할 때마다 필요한 부분을 컴파일 하는 반면에, ART의 AOT 컴파일러는 처음 인스톨 할 때 필요한 컴파일 작업을 다 해놓기 때문에 생기는 근본적인 한계[13]이다.
또한 킷캣까지 대부분의 앱은 런타임을 모두 달빅에 초점을 잡아 개발했기 때문에 달빅VM에서 잘 돌아가던 앱들이 ART 환경에서는 안 돌아가는 호환성 문제가 발생한다. [14] 그리고, 킷캣~롤리팝 초기(5.0) 기준으로 ART는 아직 적용 초기 단계인지라 사용자도 구글도 밝혀내지 못한 잠재적인 문제들이 산재해 있을 가능성이 있다. [15] 다만 15년말 현재는 이미 5.1.1을 넘어 마시멜로와 안드로이드 N(7.0)을 향해 가고 있는 만큼 이러한 미검증의 문제는 초기에 비해 적어졌다고 할 수 있다.
안드로이드 7.0 누가에서는 최초 설치시에는 JIT를 사용하고, 차후 기기를 사용하지 않을 때나 충전 중일 경우 컴파일을 조금씩 하여, 자주 사용되는 앱을 AOT방식으로 전환하는 것으로 바뀌었다. 즉, 양 방식의 장점을 합치고 단점을 극복하려 시도한 것이며 실제로 애플리케이션의 설치 속도가 기존 AOT 방식에 비해 매우 빨라졌다.
3.6.1 상용 앱의 속도는 얼마나 개선될 것인가?
ART 적용 이전에도 코드 보안이나 성능 보장이 매우 중요한 앱 개발은 NDK를 이용한 C/C++ 프로그래밍을 통해 이루어져 왔다. 상용 앱 내부에는 앱에 따라서 어느 정도 네이티브 코드가 포함되어 있기도 하다는 것. 최적화가 될 만큼 되어 있는 이러한 앱들에 대해서는 유의미한 성능 개선이 이루어지지 못할 가능성 역시 존재한다.
3.7 오해
초기에 배터리 실사용 시간이 ART가 달빅보다 불리하다는 오해가 있었다. 이런 오해를 받게 된 원인은 ART가 처음 도입 된 킷캣이나 롤리팝에서 ART를 사용할 때의 배터리 타임이 짧았기 때문으로 보인다. 그러나 이것은 달빅이 좀 더 긴 역사를 가져서 더 안정화가 되었기 때문일 뿐이지 ART의 구조 자체에 근본적인 원인이 있는 것이 아니다. 실제로 롤리팝에 비해 마시멜로우에서 배터리 수명이 크게 향상되었다.
4 ART와 가상머신
ART 또한 달빅과 같은 가상머신의 일종이다. 기존 안드로이드는 DEX 파일을 Dalvik 가상머신위에 올려두고 필요에 따라 실시간으로 컴파일하는 방식이었다. ART를 사용하는 경우는 DEX 파일을 미리 컴파일하여 OAT 파일에 저장해두고 실행 돌리는 것으로 변했을 뿐이다. 기존의 DEX 파일을 dex2oat 라는 변환기를 이용해서 생성하고 실행한다. 오랜기간 위키에 잘못된 정보가 쓰여있어 반박을 주석으로 달아놓는다.[16]
오해의 소지가 있어서 설명을 추가한다. OAT 파일은 DEX를 컴파일한 native machine code를 담고 있으며, 가상머신을 거치지 않고 바로 실행된다. 하지만 ART를 사용한다고 해도 Dalvik에서 실행하는것과 논리적으로 동일한 결과물을 제공해야 하기 때문에, OAT에 저장된 native machine code에는 가상머신의 상태를 흉내내기 위한 부가적인 코드들이 잔뜩 들어가게 된다 (디버깅을 위해 필요하다. 물론 JIT compiler가 뱉어낸 machine code도 비슷하게 생겨먹었다). 다시 말해서 ART를 사용하는 경우 앱이 가상머신 위에서 작동하지는 않지만 가상머신으로부터 완전히 자유롭지도 않다.
5 Xposed 프레임워크
참고로 Xposed는 상당한 기간동안 ART를 지원하지 않아 ART상태에서 설치를 시도할 경우 강제로 달빅으로 전환해버렸다. 킷캣 때의 CyanogenMod에서는 ART를 선택해도 ART로 바뀌지 않고 달빅으로 계속 유지되는 오류가 있었다. 이러한 현상은 런타임을 달빅으로 설정한 상태에서 Xposed 프레임워크를 설치해 놓고, 그 다음 런타임을 다시 ART로 전환할 때나, 2013년 11월부터 2014년 1월 사이에 나온 커스텀롬(CM11 나이틀리 포함)이나 개발자가 자체적으로 ART를 제거한(!) 커스텀롬을 사용할 경우에 발생했다.[17]
그리고 안드로이드 롤리팝 런칭 이후에도 Xposed 개발팀은 감감무소식이어서 사용자들의 애를 태웠으나, 몇 개월 지난 뒤 ART 및 안드로이드 5.0 롤리팝을 위한 Xposed를 공개했다. 그 뒤 어떤 유저가 비공식으로 포팅한 안드로이드 5.1용 Xposed가 공개되었고, 이윽고 8월 31일 공식적으로 안드로이드 5.1을 지원하게 되었다.[18] 또한, 이후 안드로이드 6.0 마쉬멜로우까지 지원하게 된다.
정리하면 현재 안드로이드 5.0 ~ 6.0 에서는 Xposed 프레임워크 및 Xposed 모듈이 거의 완전하게 돌아간다고 보면 되겠다.- ↑ 킷캣까지는 x86, mips 아키텍처는 칩셋 제조사나 기기 제조사에서 자체적으로 포팅했다.
- ↑ 추가로 크롬 OS에도 아직 베타이긴 하지만 ART를 지원은 가능한 구문이 있다. 이걸로 안드로이드-크롬OS간 네이티브 앱 호환이 가능하기도 하다.(장기적으로는 안드로이드 앱의 크롬북/크롬박스판으로의 확장을 노린 거기도 하다.) 그리고 이걸 구글에서는 Apps Runtime on Chrome, 즉 ARC라고 부른다. (그래도 근본적으로는 ART와 거의 같은 방식인데다 안드로이드-크롬OS간 크로스 컴파일링이 가능.)
- ↑ 이는 Java에 대한 권리가 다른 곳에 있기 때문이다. 자세한 것은 각각 항목 참조.
- ↑ 4.4 킷캣 버전에서는 개발자 설정 내에서 선택할 수 있도록 되어 있으나 기본은 아니다
- ↑ UI에서라던가...
- ↑ 윈도RT를 써본 유저라면 매우 잘 알고 있을 것이다.
- ↑ 다만 이 가상머신은 플랫폼 의존적이다.
- ↑ 물론 이렇게 한 단계 끼어든 것 때문에 속도나 자원의 희생은 어쩔 수 없는 것이지만
- ↑ 물론 자바 개발자 뿐만 아니라 프로그래머 전체에 대한 열악한 처우에서 나온 말이기는 하지만, 왜 하필 이 드립의 주인공이 자바일까 생각해 보면 답이 나온다.
- ↑ 다만 마지막 문장은 조금 생각해봐야 할 것이, 안드로이드는 아이폰보다 램은 두세 배로 장착하고도 부드럽기는 아이폰이 훨씬 부드럽다는 오명을 들어와야만 했고, 그 H/W가 뛰어나다는 회사는 S/W는 어찌됐든 H/W만 뛰어나면 장땡이라는 마인드로 초기 몇 년간은 (그리고 어쩌면 아직도) 넥서스 시리즈의 사양이 한참 떨어지는 동세대 제품보다 체감성능은 안 나오는 상황을 여러번 만들어내기도 했다. 소프트웨어 회사인 구글이, 비효율적인 구조임을 훤히 알면서도 단지 하드웨어빨이면 된다는 마인드를 가지고 개발을 밀어붙였을까?
- ↑ AOT 컴파일러에 의해 진행된다. 마치 리눅스에서 패키지 관리자를 통해 소스 코드를 받아 make 후 install 하는 것과 같은 느낌으로 보면 된다.
- ↑ 정확히는 자바 바이트코드
- ↑ 이러한 과정을 아예 없앨 순 없으니 인스톨시에 몰아서 하는 것으로 위에 거론된 장점들을 얻은 것이다. 세상에 공짜는 없는 법
- ↑ 당연한 소리겠지만 모든 앱이 그러진 않는다. 또한 롤리팝부턴 ART가 기본이므로 계속 저렇게 앱만들다가는 사장되기 딱 알맞다.
- ↑ 애초에 킷캣은 ART가 기본값인 경우가 거의 없고 사용자가 활성화 해줘야만 하는데다가, 그나마 구버전으로 출시되어서 업데이트로 킷캣을 쓰는 기기는 ART 옵션조차 아예 지원 안 하는 경우도 있다.
- ↑ 라이브러리 안에는 lib_dvm.so라는 파일도 존재하고 있어 이것은 가상머신이 아니라는 증거조차 되지못한다. 가상머신을 사용하지 않는 다면 안드로이드 자체가 x86 등에 대한 호환성을 잃어버렸어야 정상이다. art 머신 구조를 분석한 논문을 봐도 미리 컴파일링해두어서 매번 컴파일 하는 것을 방지할뿐이다,
- ↑ 2013년 11월부터 2014년 1월은 안드로이드 킷캣과 ART 런타임이 새로이 출시된 지 얼마 지나지 않은 시기로, ART에 대한 대응 업데이트가 늦어 그 시기에 나왔던 CM11을 포함한 킷캣 커스텀롬들은 대체적으로 ART를 지원하지 않았으나 2014년 1월 이후 모두 지원한다. 단, 요즘 나오는 킷캣 커스텀롬들 중에서도 ART는 삭제하고 오로지 달빅만 런타임으로 돌리는 커스텀롬들도 존재한다.
달빅성애자?아무래도 달빅을 계속 사용하고 싶어하는 유저들을 위해서 일부러 ART를 제거하고 일부러 달빅 최적화에 초점을 맞춘 듯. 각 커스텀 롬마다 ART 제거 여부는 개발자의 xda 포럼이나 개인 홈페이지 내의 체인지 로그 등에 있으니 ART를 사용하고 싶은 위키러는 반드시 확인할 것. 안 그러면 귀찮게시리 롬 다시 밀어야 한다(...). - ↑ 하지만 이 Xposed는 AOSP 계열 펌웨어만 지원하고 제조사 커스텀 펌웨어는 지원하지 않는다. 삼성 갤럭시 등에서 쓰고 싶다면 삼성 롤리팝용 Xposed를 찾아 보자. 국내의 어떤 개발자가 포팅하였다.