클래스 로더를 통해 런타임 데이터 영역에 배치된 바이트 코드를 명령어 단위로 읽어서 실행한다. 실행 엔지는 바이트 코드를 실제로 JVM 내부에서 기계가 실행할 수 있는 형태로 변경해준다.
이 수행 과정에서 실행 엔지는 인터프리터와 JIT 컴파일러 두 가지 방식을 혼합하여 바이트 코드를 실행한다.
바이트 코드 명령어를 하나씩 읽어서 해석하고 바로 실행한다.
JVM 안에서 바이트코드는 기본적으로 인터프리터 방식으로 동작한다.
다만 같은 메소드라도 여러 번 호출이 된다면 매번 해석하고 수행해야 돼서 전체적인 속도는 느리다.
위의 Interpreter의 단점을 보완하기 위해 도입된 방식으로 반복되는 코드를 발견하여 바이트 코드 전체를 컴파일하여 Native Code로 변경하고 이후에는 해당 메서드를 더 이상 인터프리팅 하지 않고 캐싱해두었다가 네이티브 코드로 직접 실행하는 방식이다.
하나씩 인터프리팅하여 실행하는 것이 아니라, 컴파일된 네이티브 코드를 실행하는 것이기 때문에 전체적인 실행 속도는 인터프리팅 방식보다 빠르다.
하지만 바이트코드를 Native Code로 변환하는 데에도 비용이 소요되므로, JVM은 모든 코드를 JIT 컴파일러 방식으로 실행하지 않고 인터프리터 방식을 사용하다 일정 기준이 넘어가면 JIT 컴파일 방식으로 명령어를 실행하는 식으로 진행한다.
자바 가상 머신은 가비지 컬렉터(garbage collertor)를 이용하여 Heap 메모리 영역에서 더는 사용하지 않는 메모리를 자동으로 회수해 준다.
C언어 같은 경우 직접 개발자가 메모리를 해제해줘야 하지만, JAVA는 이 가비지 컬렉터를 이용해 자동으로 메모리를 실시간 최적화 시켜준다. 따라서 개발자가 따로 메모리를 관리하지 앟아도 되므로, 더욱 손쉽게 프로그래밍을 할 수 있도록 해준다.
일반적으로 자동으로 실행되지만, 단 GC가 실행되는 시간은 정해져 있지 않다.
특히 Full GC가 발생하는 경우, GC를 제외한 모든 스레드가 중지되기 때문에 장애가 발생할 수 있다.