자바는 어떻게 실행될까?
자바는 자바 컴파일러로 가상의 기계어, 그러니까 바이트코드로 소스코드를 변환한다.
바이트코드는 JVM에서 읽혀서 OS에 실행된다.
이러면 무슨 특징이 생기는가?
컴파일 방식의 장점을 일부 갖는다.
- 소스코드를 노출하지 않는다. (바이트코드도 기계어파일처럼 해석 및 역컴파일이 사실상 불가하다)
- 컴파일 과정에서 문법검사가 완료되므로, 문법검사로 인한 속도저하는 없다.
그리고 가상의 기계어(바이트코드)를 사용하므로..
- 특정 CPU에 종속적이지 않다. 실제 기계어로 바꾼다면 CPU마다 다르게 번역해줘야 한다.
- OS에 맞는 JVM이 있다면 그 JVM으로 바이트코드를 플레이(실행)하면 된다.
- 진짜 기계어가 아닌, '바이트코드'이므로 진짜 기계어보다 느리다.
- 바이트코드는 느리다고 해도 OS에 상관없이 실행할 수 있다는 게 아주 큰 장점이다. 이득이 크다.
Java랑 비교를 자주 하는 언어가 C# 이다.
MS가 밀어준 C# 은 어떻게 컴파일될까?
.cs 소스파일을 컴파일하면 CIL(Common Intermediate Language)로 변환된다. 이 CLI는 .NET을 통해서 실행된다.
CIL은 공통 중간 언어로 번역되는데, 이건 MS가 가진 visual basic 을 컴파일해도 만들 수 있다. 그래서 공통이다.
CIL 바이트코드와 같은 가상의 기계어이다.
- C > C++ > JAVA > C# 순으로 나왔다. 나중에 만든 C#도 하이브리드 방식을 차용했다.
하이브리드 방식은 중간 코드가 바로 실행할 수 있는 기계어가 아니라 속도가 느린 단점이 있어도 왤케 많이 쓰나?
젤 큰건 CPU 성능이 계속 겁나게 좋아졌기 때문이다.
그런데 가전제품도 인터넷에 연결되고 있고, 자동차는 그냥 소프트웨어 덩어리가 되고 있는게 2010년부터 쭉 이어져오는 상황이라 C 개발자가 또 각광을 받았다. 다만 가전제품의 프로세서도 성능이 높아지는 추세라서 Java를 쓰는 경우도 늘어나고 있다.
참고로 C# 은 인기가 없다. MS에서 윈도에서만 실행가능하도록 하고 공개를 안했었기 떄문이다. 나중에 사티아 나델라 왔을 때 오픈소스로 풀었으나 이미 자바에 밀렸기 때문에 인기가 아직도 좋지 않은 편이다.
삼성 things 를 들어본 적이 있는가? SmartThings, 가전 제품을 앱으로 연결하여 제어할 수 있게 하는 솔루션을 가진 회사인데 삼성이 인수했다. 이건 자바 기반이다. 위에 적었듯 스마트 디바이스도 성능이 좋아지고 있다.
2005에 C가 자바를 인기도 역전한 적이 있었다. 그 이후 자바스크립트와 파이썬이 치고 올라온다.
지금도 C는 인기가 많다. IoT 영역에 개발할 게 많은게 주된 이유다.
JIT
Just In Time을 의미하는 JIT은 실행하는 시점에 자주 실행하는 코드를 진짜 기계어로 바꿔놓고 그 기계어를 실행하는 걸 말한다. 왜 그런 일을 하는가? 당연히 속도 때문이다. 진짜 기계어가 속도가 빠르기 때문이다.
중간 언어를, 자바로 치면 바이트 코드를 갖는 언어는 JIT 방식을 대부분 차용한다고 봐도 된다.
JIT은 모든 기기에서 다 중요하지만 안드로이드같이 전성비가 중요한 경우 더 그렇다.
자바는 1995년 5월 23일 출시됐다. JIT은 언제 만들어진 개념일까?
http://java.sun.com/features/2000/06/time-line.html
October 25, 1996 Sun announces first Just-In-Time (JIT) compiler for Java platform
Also, from wikipedia: Since JRE version 1.2, Sun's JVM implementation has included a just-in-time compiler instead of an interpreter. http://en.wikipedia.org/wiki/Java_(Sun)
생각보다 오래 걸리지 않았다. 96년 10월경이다. JIT 도입 이전 방식은 지금까지 자바에 대해서 이야기했던 것처럼 전체 소스코드를 바이트코드로 자바컴파일러가 변환한 후 JVM에서 그 바이트코드를 실행하는 것이었다. (그러므로 JIT & AOT을 언급하지 않으면 현대 자바의 실행 원리를 모르는 것이다)
JIT이 도입된 이후에는 자바 소스코드를 실행하기까지 어떻게 될까?
- 핵심은 JVM이 자주 실행되는 일부 명령은 바로 그 시점에[JIT] 기계어로 컴파일하여 보관[caching]해둔다.
- 일부는 기존 방식처럼 JVM이 바이트코드를 실행하고,
- 보관된 명령들은 기계어를 직접 실행한다.
JIT은 실행할 때 [일부 명령 기계어 컴파일&캐싱]이므로 실행했을 때 컴파일로 인해 일시적 속도저하가 있는 문제가 있다. 이를 해결할 목적으로 만든 방법이 AOT다.
JIT도 그렇고 AOT도 그렇고, 이름이 시원시원하게 직관적이라 좋다.
AOT는 Ahead Of Time 이다. [그 시점에 앞서서] 라는 의미로, 실행시점보다 더 앞서서 컴파일 해두는 것이다.
안드로이드는 플레이스토어에서 앱을 다운로드 받으면, 휴대폰에서 앱을 미리 컴파일하여[Install] 기계어를 캐싱해둔다. 앱을 실행하면 캐싱된 기계어를 직접 실행한다. GPT가 요약해 준 내용을 보자.
Android에서 AOT (Ahead-of-Time) 컴파일이 도입된 시점은 Android 5.0 (Lollipop)입니다. 이전 버전에서는 Dalvik 가상 머신이 사용되었고, Dalvik은 JIT (Just-In-Time) 컴파일을 사용했습니다. Dalvik은 앱을 실행할 때 바이트코드를 런타임에 네이티브 코드로 컴파일하는 방식이었습니다.
Android 5.0부터는 ART (Android Runtime)가 도입되었고, ART는 Dalvik의 JIT 컴파일 방식 대신 AOT 컴파일을 기반으로 하는 방식을 채택했습니다. ART의 AOT 컴파일은 앱을 설치할 때 DEX 파일을 네이티브 코드로 미리 변환하여 저장하는 방식입니다. 이로써 앱이 실행될 때마다 바이트코드를 네이티브 코드로 변환하는 JIT 컴파일의 런타임 오버헤드를 줄이고, 초기 실행 속도를 향상시켰습니다.
ART의 AOT 컴파일은 안드로이드 성능의 향상과 배터리 수명의 개선을 목표로 하였으며, 이후의 안드로이드 버전에서도 계속해서 개선되어 사용되고 있습니다.
AOT 방식은 실행속도가 빠른데, 설치할 때 기계어로 바꿔줘야 하기 때문에 설치시간이 필요하다.