우선 컴파일이 뭔지 알아야 한다.
컴파일은 번역기라고 생각하면 됨. 어떤 언어로 구성된 프로그램을 다른 언어의 동일한 프로그램으로 만드는 것을 컴파일 이라고 한다.
그럼 코틀린과 자바 언어가 컴파일 되는 과정을 보자
1. 자바와 코틀린으로 구성된 파일 .java, .kt가 있음
2. 각각의 javac 와 kotlinc에 의해서 자바 바이트 코드로 컴파일 된다. .class
3. 이 자바 바이트 코드는 jvm의 jit컴파일러에 의해서 기계가 이해 할 수 있는 언어로 변경된다.
4. 해독된 기계언어를 메모리에 할당 후, cpu에 의해 실행
일반적인 jvm사용한 컴파일 방식과 달리 안드로이드에서는
DVM(Dalvik Virtual Machine) 과 ART(Android Run Time)를 사용한다.
그 이유와 두개의 차이는 뒤에서 알아보도록 하자
코틀린은 java, js 등등과 호환 가능한 언어임
여기서 코틀린에 대한 특징을 하나 더 말하자면, 람다형으로 사용하는 코틀린 언어는 인라인을 통해서 이루어지기 때문에 객체 증가로 이루어 지지 않기 때문에 가비지컬렉션(GC)가 늘어나는 일로 멈추지 않는다.
그럼 JVM에서는 어떻게 동작을 하는 걸까?
Java 바이트 코드는 JRE(Java Runtime Enviroment)위에서 동작한다.
JRE는 어플리케이션을 생성하고 실행하기 위한 일련의 구성요소다.
JRE는 JDK(java development kit)의 구성요소의 일부이고, JRE는 JVM, 자바 클래스 라이브러리, 자바 클래스 로더로 구성된다.
JVM은 자바 클래스로더를 통해 어플리케이션을 읽어들여, API와 함께 실행한다.
왼쪽 그림과 같이
jvm은 클래스 로더가 자바 바이트 코드 런타임 데이터 공간에 로드하고, 실행 엔진이 자바 바이트 코드를 실행한다.
클래스 로더
컴파일 타임이 아닌 런타임에서 최초로 클래스를 참조 할 때, 이를 동적으로 로드하고 링킹해주는 역할을 한다.
런타임 데이타 영역
6개의 영역으로 나눌 수 있다(pc 레지스터, jvm스텍, 네이티브 메서드 스텍, 힙, 메서드 영역, 런타임 상수 풀)
여기서 힙, 메서드 영역, 런타임 상수 풀은 모든 스레드가 공유하고 있다.
실행 엔진
바이트 코드를 실제 기계 내부에서 실행 할 수 있는 형태로 변경한다. 이는 두가지 방법이 있는데
1. 인터프린터
명령어를 하나씩 읽어서 실행 , 바이트 코드 하나하나의 해석은 빠르지만 인터프린팅의 결과 실행은 느리다
2. JIN(just in time)
인터 프린팅 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일 하여 네이티브 코드로 변경 후 실행, 인터프린팅 보다 빠르고, 캐쉬를 통해서 개선이 가능
.class -> .jar
안드로이드의 컴파일 방식
안드로이드는 바이트 코드를 덱스 .dex 바이트 코드로 변환하여 사용한다.
위의 dvm은 JIT 방식을 사용하지만 ART은 AOT(Ahead Of Time)을 사용한다.
jit방식은 실행 도중에 컴파일이 실행되는 방식으로 성능이 좋지 않지만, aot방식은 앱 인스톨과 함께 네이티브 코드로 컴파일 되어 설치되어, 실행중에 컴파일을 할 필요가 없게 만들어, 빠른 성능을 보인다.
가비지컬렉션, 디버그등등이 개선됨
안드로이드가 jvm을 버린 이유는 , 다양한 네이티브 언어를 지원하여 느리기 때문에 안드로이드에서만 사용이 가능한 방법을 찾은것?
아래는 dvm, art의 컴파일 구조임
참고
https://d2.naver.com/helloworld/1230
https://medium.com/@banmarkovic/process-of-compiling-android-app-with-java-kotlin-code-27edcfcce616
https://medium.com/@logishudson0218/안드로이드-컴파일-방식-dalvikvm-art-b5d64350489f
'안드로이드 읽어보기 > 1. Android Platform' 카테고리의 다른 글
1) 안드로이드 아키텍쳐 (0) | 2022.04.24 |
---|---|
0. 시작하기 전에 (0) | 2022.04.22 |