Android Process Virtual Machine(JVM, DVM, ART)에 대해 알아본다.
Virtual Machine
– Virtual Machine은 물리적 하드웨어 시스템에 구축되어 자체 CPU, Memory, Network Interface 및 Storage를 갖추고 가상 컴퓨터 System으로 작동하는 가상 환경.
– Hypervisor(VM을 생성하고 구동하는 Software. VMM이라고도 불리며, 운영 제제와 VM의 리소스를 분리해 VM의 생성과 관리를 지원)를 통해 하드웨어에서 VM의 리소스를 분리하고 적절히 Provisioning(사용자의 요구에 맞게 시스템 자원을 할당, 배치, 배포해 두었다가 필요시 시스템을 즉시 사용할 수 있는 상태로 미리 준비해 두는 것)하여 VM에서 사용할 수 있게 함.
– 사용 이유 : Server 통합이 주된 이유. 대부분의 운영체제와 Application 배포는 Bare Metal, 즉 하드웨어 상에 어떠한 소프트웨어도 설치도 되지 않은 상태에 배포를 진행함. 이때, 소량의 가용 물리적 리소스만을 제공. VM을 사용할 경우 각 물리 서버에 수많은 가상 서버를 배치하여 하드웨어 활용률 개선 가능. 이를 통해 하드 드라이브 or 하드 디스크와 같은 물리적 리소스 추가 구매 필요 사라짐. 데이터센터 내 전력, 공간 및 냉각의 필요성 감소. 하드웨어를 통해서만 가능했던 장애 조치와 이중화를 지원하여 추가적인 재해 복구 옵션 제공.
– Security : VM이 격리되어 존재. Host OS를 볼 수 없음. Virus App Code는 시스템에 직접 영향을 미칠 수 없음. App과 System을 안정적으로 유지 가능.
– Platform Independent : 다양한 Architecture의 기기에서 실행 가능.
Process VM / System VM
– Process Virtual Machine : Platform(운영체제) 독립적인 환경에서 Program을 실행하도록 설계됨.
– System Virtual Machine : 실제 Machine을 대체하도록 제공하는 Full Virtualization Machine.
Dalvik Architecture
– Dalvik은 Process VM으로 Android용으로 제작된 Application을 실행하는 데 사용.(현재는 단종되었으며, ART에서 바이트코드 형식을 사용)
– Android 4.4 “Kit Kat” 및 이전 버전에서 Android Software Stack에 필수적 요소로 사용.
– Android용 Program은 일반적으로 Java로 작성되고, JVM용 바이트코드로 컴파일 진행. 이후, Dalvik 바이트코드로 변환되어(Dalvik EXecutable 및 Optimized Dalvik EXecutable) 파일에 저장됨.
– dx Tool을 이용하여 Java의 class파일을 dex형식으로 변환 가능(여러 class 파일이 하나의 dex파일에 포함될 수 있음 – 중복 문자열 및 기타 상수는 공간 절약을 위해 dex에 한 번만 포함됨)
– 압축되지 않은 dex 파일이 동일한 class 파일에서 파생된 Jar 파일보다 크기가 적음
– Dalvik 실행 파일은 Mobile Device에 설치 시 재 수정 가능. 최적화를 위해 특정 데이터에서 바이트 순서를 바꾸거나 간단한 데이터 구조와 함수 라이브러리를 In-line으로 연결할 수 있으며, 빈 객체를 단락가능.
– Dalvik 이후에 나온 ART는 동일하게 바이트코드 및. dex파일 사용(. odex파일 X).
– Android 5.0 “Lollipop” 부터는 ART가 Dalvik을 완전히 대체하여 사용됨.
Performance
– JVM의 Stack-Based Machine 방식과 Dalvik의 Register-Based 방식의 장단점이 있음.
– Stack-Based Machine 방식은 Stack에 Data를 로드하고 해당 Data 조작을 위해 명령어 사용이 필요. 동일한 고급 코드를 구현하려면 Register-Based 방식보다 더 많은 명령어를 사용. 많은 메모리 사용이 요구되므로, Android에서 빠른 동작 진행이 불가능.
– Register-Based Machine은 명령어가 적은 대신 Source와 해당 Register Encoding 진행 필요. 이와 같은 차이는 VM Interpreter에 영향을 줌. POP & PUSH 과정이 없기 때문에 같은 덧셈이라도 하나의 명령으로 충분. Stack 기반에서는 할 수 없는 명령어 최적화를 적용 가능. 즉, 적은 메모리 사용으로 빠르게 동작이 가능. 하지만, Stack 기반보다 명령어의 길이가 길어짐(명령어의 수는 적지만, 더 복잡한 VM 명령어 필요). 피 연산자의 주소를 명시해줘야 하므로 평균적으로 길 수밖에 없음.
– License – JVM은 GPL License이며, Android 관련 내용은 Apache License가 대다수 이므로, License 문제에서 JVM을 사용하는 것이 적합하지 않아 개발된 것이 Dalvik VM.
– Android 2.2 “Froyo”는 추적 기반 JIT(Just-In-Time) 컴파일을 Dalvik에 도입하여 애플리케이션이 실행될 때마다 지속적으로 애플리케이션을 프로파일링하고 자주 실행되는 바이트코드를 Dalvik이 애플리케이션의 나머지 바이트코드를 해석하는 동안 “Traces”이라고 하는 짧은 바이트코드 세그먼트의 실행을 통해 컴파일하여 애플리케이션 실행 최적화.
Java Virtual Machine(JVM)
– Process Virtual Machine의 일종으로 “한 번 작성한 이후에 어디에서나 실행” 원칙에 따라 Java/Kotlin으로 작성된 프로그램을 모든 장치 또는 운영체제에서 실행할 수 있음.
– IntelliJ /Android Studio와 같은 IDE는 Java 컴파일러(javac)를 사용하여 Java 코드(.java)를 Java 바이트 코드()로 컴파일(.class)
– 이후, Runtime 환경에서 JVM은 이를 Runtime 환경이 이해할 수 있는 Machine 사양 명령어 세트로 변환됨.
– JVM Start -> Main Thread Start -> Class loader를 사용하여 Memory에 .class Load -> Byte code 및 Java의 보안 제한 확인 -> 바이트코드가 명령어를 번역하고 실행 -> class를 unload 진행 -> Main Thread 종료 -> JVM 종료(Java 코드를 미리 Native 코드로 Compile 후 실행 가능. Java 코드를 직접 해석 또한 가능.
Android RunTime(ART)
– Android Application 및 System Service에서 사용, 관리되는 런타임. Dalvik VM을 대체하는 ART는 Application의 Byte Code를 장치의 런타임 환경에서 실행되는 기본 명령어로 변환.
– ART는 메모리가 부족한 장치에서 여러 VM을 실행하도록 설계되었고, 이전 버전과의 호환성 유지를 위해 Dalvik과 동일한 입력 바이트코드 (표준 Dalvik EXecutable(.dex) 파일)도 사용. 이 파일은 Android에서도 메모리 공간을 최소화하도록 설계됨.
– Android 5.0 “Lollipop”부터 기본으로 적용됨.
JIT(Just-In-Time) / AOT(Ahead-Of-Time)
– JIT는 Android 2.2 “Froyo”부터 적용된 Dalvik VM 내부의 컴파일러. 바이트 코드를 VM에서 기계어로 번역한 결과를 캐시에 저장. 해당 바이트 코드를 실행해야 하는 경우 캐시의 내용을 불러오므로, Performance가 개선되었지만, 별도의 메모리 캐시가 필요하여 일반적인 인터프리터 방식보다는 더 많은 메모리 공간 필요.
– AOT는 Android 4.4 “Kitkat”에 추가된 컴파일러로써, ART 내부의 컴파일러. Dalvik VM의 JIT와는 달리 Application이 설치되는 시점에 전체 Byte Code를 기계어로 번역하므로, 설치 시간이 오래 걸리는 단점이 있지만, Runtime에서 Byte Code 해석 시간을 제거하여 전체적인 Performance가 좋아지고, 배터리 수명이 향상됨.
Dalvik VM / ART
– Dalvik VM은 JIT Compiler 기반. ART에도 JIT Compiler가 포함되어 있지만, 새로운 AOT Compiler를 통해 Runtime 성능을 개선하고 Application 및 System Update 속도를 향상.
– Garbage Collector 최적화(일시 중지 횟수 감소).
– 향상된 배터리 수명과 Native Code 직접 실행을 통한 시작 시간 단축.(AOT가 설치 시 Compile되어 런타임 성능이 더 빠름)
– DEX 파일을 더 간결한 기계어로 변환
– 더 나은 디버깅 지원(전용 샘플링 프로파일러, 자세한 예외 보고 및 특정 필드에 대한 감시 점 설정 기능).
Garbage Collector(GC)
– Garbage Collector(GC)는 “Stop-world” 이벤트로 Application 성능에 영향을 줄 수 있음. 이로 인해 Frame 정지와 UI 응답 저하 발생 가능. 기본적으로 GC는 CMS(Concurrent Mark Sweep)방식을 사용. Dalvik VM에 비해 ART는 일시 중지 횟수가 2회에서 1회로 줄어들어 성능 개선.
– 이외에도 ART의 GC는 Dalvik의 GC에 비해 GC처리량이 증가하였고, 최근에 할당된 수명이 짧은 객체 정리 시 시간이 감소하였으며, Application이 Process의 상태를 Background 혹은 Cache로 변경할 때, Heap압착을 진행하여 Background Memory 사용량을 줄일 수 있는 등 많은 부분이 개선됨.
Reference
– https://blog.daum.net/creazier/15311138
– https://www.charlezz.com/?p=42686
– https://en.wikipedia.org/wiki/Dalvik_(software)
– https://medium.com/android-news/virtual-machine-in-android-everything-you-need-to-know-9ec695f7313b