Search

JVM : Java Virtual Machine

JVM이란?

자바와 운영체제 사이에서 중개자 역할을 수행하며, 자바가 운영체제에 구애 받지 않고 프로그램을 실행할 수 있도록 도와준다.
다른 하드웨어와 다르게 레지스터 기반이 아닌 스택 기반으로 동작한다.
1.
자바 컴파일러에서 자바 소스 파일(.java)를 바이트 코드(.class) 파일로 변환한다.
2.
JVM의 Class Loader에서 바이트 코드 파일을 읽은 다음에 복잡한 과정을 거쳐서 어떤 운영체제에서도 프로그램을 실행할 수 있게 만든다.
만약 자바 소스 파일을 Mac에서 만들었고 윈도우에서 이 파일을 실행하고 싶다면 윈도우용 JVM만 설치하면 된다.
→ 즉, JVM은 운영체제에 종속적인 특징을 갖고 있다.

JVM의 메모리 구조

1.
Garbage Collector(GC)
동적으로 할당된 메모리를 자동으로 관리한다.
GC는 더 이상 참조하지 않는 객체들을 식별하고 이를 제거하여 메모리 누수를 방지한다
GC는 이 페이지에서 자세하게 다루도록 한다.
2.
Execution Engine
바이트코드를 실제 머신 코드로 변환하고 실행하는 역할을 한다.
Execution Engine은 Java 소스 코드가 컴파일 된 바이트코드를 해석하고 컴파일한다.
GC와 협업하여 메모리 관리와 효율적인 코드 실행을 돕는다.
구성요소
Interpreter : 바이트코드를 한 줄 씩 해석하여 실행한다. 한 줄씩 해석하기 때문에 성능이 낮다.
JIT Compiler : Interpreter 의 성능을 개선하는 역할을 한다. 반복되는 코드는 JIT Compiler가 캐싱하여 가지고 있고 이후에는 해당 코드를 직접 실행한다.
3.
Class Loader
JVM내로 바이트 코드 파일(.class)을 가져와 런타임에 클래스를 동적으로 로드한다.
이를 JVM의 RunTime Data Area에 배치한다.
구성요소
Bootstrap Class Loader : 가장 기본적인 클래스 로더로 java.util 등 핵심 라이브러리 클래스를 로드한다.
Extension Class Loader : JVM에 확장된 기능을 제공하는 라이브러리 클래스를 로드한다 (디렉토리 내 jar 파일)
Application Class Loader : 응용 프로그램 클래스 로드로 사용자 정의 라이브러리를 로드한다. 개발자가 정의한 애플리케이션 클래스들이 로드된다.
User-Defined Class Loader : 개발자가 직접 구현한 클래스 로더이다. 특별한 로딩 방식을 구현할 때 사용한다. ex) 암호화된 파일에서 클래스를 로드하는 방식 등…
클래스 로더가 클래스를 로더할 때는 가장 먼저 상위 클래스 로더에 요청을 전달하고 상위 로더가 해당 클래스를
로드할 수 없는 경우에만 자신이 로드하는 구조이다. 이를 통해 클래스 로딩의 일관성을 유지한다.

JVM의 RunTime Data Area

JVM은 프로그램의 효율성을 위해 메모리 영역을 여러 영역으로 나누어 관리한다.
1.
Static Area(Method Area)
JVM이 시작될 때 생성되어 JVM이 종료될 때 까지 존재하는 메모리 영역이다.
클래스 파일에서 로드된 클래스와 인터페이스의 구조 정보를 저장한다.
메서드, 클래스 메서드, 필드, 메서드의 바이트코드, 런타임 상수 등이 이 곳에 저장된다. ( 정적(static) 필드와 클래스의 구조만 가지고 있다 )
크기는 고정될 수도 있고 동적으로 확장될 수도 있다.
특징
모든 스레드가 공유하는 영역이다.
static 변수도 이 영역에 저장된다.
static 변수 : 메모리에 고정적으로 할당되어 프로그램이 종료될 때 해제되는 변수
대부분의 객체가 이 영역에서 생성되며, 프로그램의 성능에 중요한 역할을 미친다.
2.
Heap Area
객체와 배열이 동적으로 할당되는 영역이다. 애플리케이션 실행 중에 생성된 객체는 이 곳에 저장되며 GC에 의해 관리된다.
특징
모든 스레드가 공유하는 영역이다.
대부분의 객체는 이 곳에 저장되며, 그렇기 때문에 프로그램 성능에 가장 큰 영향을 미친다.
GC에 의해 관리된다.
3.
Stack Area
각 스레드마다 존재하는 메모리 영역으로 메서드 호출 시 생성되는 프레임이 저장된다.
로컬 변수, 메서드 호출 시 전달되는 매개변수, 메서드 호출과 관련된 데이터(리턴 주소 등)이 저장된다.
LIFO 구조로 관리되며 메서드가 종료되면 해당 프레임이 제거된다.
Stack Area가 가득 찼을 시 StackOverFlowError가 발생한다.
4.
PC Register
각 스레드마다 하나씩 존재하며 현재 실행 중인 JVM 명령어의 주소를 가르킨다.
JVM이 특정 명령어를 실행하는 위치를 추적하는 데 사용된다.
5.
Native Method Stack
자바가 아닌 네이티브 언어로 작성된 코드를 실행하는 데 사용되는 스택이다.
Method Area와 비슷하지만 Method Area자바 바이트 코드를 실행하고 Native Method Area네이티브 코드 실행에 사용된다.
6.
MetaSpace
Java 8부터 도입된 영역으로 클래스의 메타데이터가 저장되는 공간
클래스와 인터페이스의 구조, 메서드, 필드, 상수 풀이 저장된다.
Method Area 와 차이점
Method Area는 JVM에서 관리하는 영역이고 MetaSpace는 OS에서 직접 관리하는 네이티브 메모리 영역이다.