자바와 운영체제 사이에서 중간다리 역할을 해줌으로써 자바가 운영체제에 독립적이게 만들어 주는 가상머신이다.
자바소스를 컴파일하면 바이트코드(.class)가 생성된다.
이렇게 생성된 클래스파일들을 엮어서 JVM이 운영체제로부터 할당받은 메모리영역인 Runtime Data Area로 적재하는 역할을 한다.
런타임 시에 동적으로 클래스를 로드한다.
class loader를 통해 Runtime Data Area에 적재된 바이트코드들을 기계어로 변경해 명령어 단위로 실행한다.
인터프리터 방식과 JIT컴파일러를 이용한 방식이 있다.
인터프리터
실행 엔진은 바이트코드를 명렁어 단위로 읽어서 하나하나 수행한다. 전형적인 인터프리터 언어의 단점인 한줄씩 수행하기 때문에 느리다는 단점이 있다.
JIT(Just In Time)
인터프리터 방식으로 실행하다 적절한 시점에 바이트코드 전체를 네이티브 코드로 변경해서 사용하는 방식이다. 네이티브 코드는 캐시에 보관되기 때문에 한번 컴파일 된 코드는 빠르게 수행된다. 하지만 JIT 컴파일 과정은 인터프리터 방식보다 훨씬 느리기 때문에 내부적으로 JVM이 해당 메서드가 얼마나 자주 실행되는지 체크해서 일정 수준을 넘을때만 실행한다.
Method Area
모든 스레드가 공유하며 static영역이라고도 불린다.
전역변수나 static으로 선언된 것들이 적재된다.
클래스, 인터페이스, 메소드, 필드, static변수, final 클래스, 접근제어자 등
Heap Area
모든 스레드가 공유하며 new 키워드로 생성된 객체와 배열을 저장한다.
GC의 대상 영역이다.
Stack Area
스레드별로 1개만 존재한다.
지역변수, 파라미터, 리턴값, 연산에 사용되는 임시값 등이 저장된다.
스택 프레임은 메서드가 호출될 때마다 생성되고, 메소드 실행이 씉나면 스택 프레임은 pop되어 스택에서 제거된다.
스레드가 생성될때 마다 생성되며 스레드마다 하나씩 존재한다.
스레드가 어디를 어떤 명령으로 실행할지에 대한 주소와 명령을 저장한다.
이걸 이용해 스레드를 돌아가면서 수행할 수 있게 한다.
자바 이외의 언어로 작성된 네이티브 코드(C, C++등 보통 성능을 위해)를 실행할 때 사용되는 영역이다.
가비지 컬렉션은 자바의 메모리 관리 방법 중의 하나로 JVM의 Heap 영역에서 동적으로 할당했던 메모리 영역 중 필요 없게 된 메모리 영역을 주기적으로 삭제하는 프로세스이다.
장점 : C나 C++에서는 이러한 가비지 컬렉션이 없어 직접 수동으로 메모리 할당과 해제를 일일이 해줘야 하는 반면 Java는 JVM에 탑재되어 있는 가비지 컬렉터가 메모리 관리를 대행해주기 때문에 개발자 입장에서 메모리 관리, 메모리 누수(Memory Leak) 문제에서 대해 완벽하게 관리하지 않아도 되는 장점이 있다.
단점 : 가비지 컬렉션(GC)이 언제 동작하는지 정확하게 알 수 없고 GC가 동작하는 동안에는 다른 동작을 멈추는 오버헤드가 발생한다.
Heap 영역에 생성된 객체가 스택영역의 참조변수와의 연결이 끊어지는 현상이 발생하면 GC의 대상이 된다.
Stop The World는 가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업이다. GC가 실행될 때는 GC를 실행하는 스레드를 제외한 모든 스레드들의 작업이 중단되고, GC가 완료되면 작업이 재개된다. 당연히 모든 스레드들의 작업이 중단되면 애플리케이션이 멈추기 때문에, GC의 성능 개선을 위해 튜닝을 한다고 하면 보통 stop-the-world의 시간을 줄이는 작업을 하는 것이다. 또한 JVM에서도 이러한 문제를 해결하기 위해 다양한 실행 옵션을 제공하고 있다.
객체가 새롭게 생성되면 Young영역의 Eden 영역으로 age-bit이 0인 상태로 할당 된다. 그리고 Eden영역이 꽉 차면 Minor GC가 발생하고, 살아남은 객체들은 Survivor0 영역으로 옮겨진다. 이과정에서 age-bit이 1 증가하게 된다.
이 과정이 반복되다 Survivor0 영역이 가득 차게되면 살아남은 객체들은 Survivor1 영역으로 이동한다. 이 과정을 계속 반복하다 객체의 age-bit값이 특정 임계값을 넘어가게 되면 Old영역으로 이동하게 된다.
Old영역이 꽉 차게되면 참조되지 않는 객체를 한꺼번에 삭제하는 Major GC가 발생한다.