JAVA 와 관련된 개발 환경에 대해 혼용해서 사용되는 용어 들이 있다.
JAVA , JVM , JDK , JRE 에 대한 정의와 개념을 간단히 정리하고
중요하게 JAVA의 바이트 코드란 어떤 것인지 , JVM의 역할과 과정 그리고 JIT Compliler 란 무엇이고 어떤 역할을 하는지를
역시 정리 합니다.
JVM ( Java Virtual Machine ) 은 java 의 컴파일 된 바이트 코드를 실행하는 가상 시스템 ( Softeware ) 입니다. 여기서 바이크 코드는 기계어 (Native 코드와는 다르다 . 바이트 코드는 실행을 위해서는 다시 인터프리팅되어 Native Code 로 변경되어야 한다.
JDK 와 JRE 의 차이점도 도식표와 같이 JRE ( Java Runtime Environmnt ) 가 JVM 에 응용프로그램을 실행 하기 위한 java 패키지 클래스 (util, math, lang, awt, swing 등등) 라이브러리와 Applet 을 포함하여 통칭하는 용어 이다. 최근 활요도가 많이 없어지 JAVA Web Start 와 같이 실행형 독립 프로그램이 포함된다.
JDK (Java Develipment Kit ) 는 이러한 JRE 에 추가로 개발을 위한 툴 , 즉 Complier, Debug tool , 기타 유틸리티를 포함하여 통칭 하는 용어를 JDK 라고 정의 할수 있다.
JIT(Just In Time Compiler) 컴파일러
JVM 이 ByteCode를 해석한다고 했는데, JVM은 기본적으로 인터프린터 방식을 사용한다.
이러한 인터프리터 과정을 통한 실행은 컴파일된 코드를 실행하는 것보다 상당히 느릴 수 밖에 없다.
Java는 이러한 단점을 개선 하기 위해 JRE에 JIT을 포함시켜 ByteCode를 기계 코드로 변환할 수 있도록 하였다.
JIT는 바이트코드 전체를 컴파일 하여 네이티브코드로 변경하고 이후에는 다시 인터프리팅 하지 않고 네이티브 코드로 직접 실행하는 방식이다.
JIT은 JVM의 일부로 동작 하면서 ByteCode를 필요한 만큼 쪼개어 실시간으로 실행 가능한 상태(Machine Code)로 컴파일 한다.
(* JIT = Just In Time 이란 용어는 "필요한 만큼만" 의미로 많은 여러 영역에서 성능 개선을 위해 사용되는 개념이다. )
보통 인터프리터 방식의 언어 구현들이 성능 향상을 목적으로 도입하는 경우가 많은데, 같은 코드를 매번 해석하는 대신 실행하기 전에 그 부분만 컴파일을 해 두고 다음부터는 컴파일된 코드를 쓰기 때문에 인터프리터의 느린 실행 성능을 개선할 수 있다.
JIT 이전부터 실행 성능 문제 때문에 바이트코드 컴파일을 도입했던 Java와 같은 언어들도 바이트코드를 해석하는 대신 컴파일된 기계어 코드를 직접 실행하는 쪽이 어쨌든 빠르기 때문에 역시 도입하고 있다.
JIT의 구체적인 동작 원리
단점이라면 초기 구동 후 얼마간은 바이트코드를 컴파일하는 데에 시간과 메모리를 소모하기 때문에 정적 컴파일된 C, C++과 같은 프로그램에 비해 초기 실행 속도와 메모리 사용량에서 손해를 본다는 것으로, 특히 실행 시간이 매우 짧은 경우에는 애써 컴파일된 코드를 제대로 울궈먹기도 전에 프로그램이 끝나는 배보다 배꼽이 더 큰 상황이 벌어지기도 한다.
크게 나눠서 HotSpot VM과 같이 메소드단위로 JIT 컴파일을 하는 방식과, 그보다 더 작은 단위에서 프로그램 실행 흐름을 실시간으로 추적하며 컴파일할 코드를 탐색하는 Tracing JIT 방식으로 분류할 수 있다.
특히 Tracing JIT의 경우에는 실행 시점에만 알 수 있는 정보를 컴파일에 적극적으로 반영하기 때문에 이론적으로는 정적 컴파일 방식보다 더 빨라질 수도 있다
사족 : 우리가 흔히 사용하고 있는 용어 중 혼선이나 오류는 무척이나 많다 . 다만 그럼에도 불구하고 살아가는데 크게 문제가 되지 않는 이유는 "개떡같이 애기해도 찰떡 같이" "알아 듣기 때문인것 같다
최근 새롭게 알게되어 스스로 놀란 용어의 정리를 아래 추가 합니다. 코드 - 플러그- 콘센트 각각의 차이를 알고 사용하고 계신가요 ?