Java
JIT(Just-In-Time)
JIT Compiler는 사용할 때 컴파일한다는 뜻이다. 자바에서 컴파일을 하면 Bytecode로 변환된다. 이 Bytecode는 기계가 바로 읽을 수 있는 형태가 아니며, Bytecode는 실제 실행될 때 다시 한 번 기계가 읽을 수 있는 형태(native code)로 interpreter를 통해 해석이 되어야 한다.
이렇게 한번에 기계어로 변환하지 않고 두 번의 과정을 거치는 이유는 Java의 최대 장점 중 하나인 machine-independent 특성 때문이다. platform independent라고도 하는데, 한 번 작성하면 어떤 기기에서도 돌릴 수 있다는 특성을 말한다.
프로그래머들은 별 걱정 없이 프로그램을 작성해서 Bytecode로 컴파일 하고, JVM(Java Virtual Machine)이 이 Bytecode를 해당 기계에 맞는 기계어로 다시 번역하는 작업을 하는 것이다. 기계어로 변환하는 작업은 OS나 CPU에 dependent하기 때문에, JVM을 만드는 사람들만 새로운 OS와 CPU에 대해서 걱정하면 된다.
JVM이 Bytecode를 기계어로 interpret(해석) 할 때, 그 기계어 코드를 캐싱하여 같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다. 이 과정을 'JIT 컴파일링' 이라고 한다. JIT 컴파일링은 실행될 때 최초 실행되기 때문에, 최초 실행에서는 조금 느릴 수 있다. JIT 컴파일러를 사용하면, 컴파일 없이 Interpret만 하는 경우보다 반복적인 작업을 할 때 더 높은 성능을 낼 수 있다.
JVM(Java Virtual Machine)
자바 소스 코드로부터 만들어지는 자바 바이너리 파일(.class)을 실행할 수 있는 스택 기반의 가상 머신이다. 대표적인 컴퓨터 아키텍처인 인텔 x86 아키텍처나 ARM 아키텍처와 같은 하드웨어가 레지스터 기반으로 동작하는데 비해 JVM은 스택 기반으로 동작한다.
C언어에서 malloc(), free() 를 통해 메모리를 통제했지만 Java는 JVM이 GC로 해당 기능을 처리한다.
플랫폼 독립적이기 때문에, 자바 프로그램들은 JVM 위에서 동작하기 때문에 어떤 플랫폼이든 JVM만 설치되어 있으면 실행 가능하다.
자바에서 프로그램을 실행한다는 것은 Class 파일을 JVM으로 로딩하고, Bytecode를 해석(Interpret) 하는 작업은 물론, 메모리 등의 리소스를 할당하고 관리하며 정보를 관리하는 일련의 작업들을 포괄한다. 이 때 JVM은 쓰레드 관리 및 Garbage Collection과 같은 메모리 재생 작업도 수행한다.
Heap Area
Young Generation :
이 영역은 Java 객체가 생성되자 마자 저장되고, 최근에 생성된 객체가 저장되는 공간이다. Java 객체가 생성되면 이 영역에 저장되다가, 시간이 지남에 따라 우선순위가 낮아지면 Old 영역으로 옮겨진다. 이 영역에서 객체가 사라질 때 Minor GC가 발생한다.
Old(Tenured) Generation :
Young Generation 영역에서 저장되었던 객체 중에서 오래된 객체가 이동되어 저장되는 영역이다. 이 영역에서 객체가 사라질 때 Major GC(Full GC)가 발생한다.
Permanent 영역 :
Class loader에 의해 load 되는 Class, Method 등에 대한 Meta 정보가 저장되는 영역으로 JVM에 의하여 사용된다. Reflection을 사용하여 동적으로 클래스가 로딩되는 경우에 사용된다. 내부적으로 Reflection 기능을 자주 사용하는 Spring Framework를 이용할 경우 이 영역에 대한 고려가 필요하다.