JVM을 이해하기

Shin·2022년 12월 1일
0

Java

목록 보기
3/6

1. JVM이란?

JVM(ava Virtual machine)

: 자바를 실행하기 위한 가상 기계라는 의미로
 *.java  파일이  javac.exe  라는  java compiler  에 의해 class 파일로 컴파일 된 자바 바이트코드를 OS에 특화된 코드로 변환하여 실행한다.

  • JVM은  OS 에 맞게 바이트코드 에서 기계어 코드로 변환하는 과정에서  interpreter  JIT compiler  를 사용하게 된다.

JVM의 실행순서

  1. Class Loader를 통해 .class 파일을 JVM에 올린다.
  2. JVM에 있는 .class 파일을  Execution Engine  Interpreter  JIT Compiler  를 통해 기계어로 해석한다.
  3. 기계어 코드(해석된 바이트 코드)는  Runtime Data Area 에 배치되어 수행이 시작된다.
  4. 실행될 클래스 파일을  Method Area(Static Area)  에 로드 후 초기화 작업을 수행한다.
  5.  Static method  Class variable (클래스 변수)를  Mehtod Area 에 저장한다.
  6. 클래스 로드가 다 되었다면, main method의 객체변수와 참조변수의 메모리 주소의 해시와 지역변수를  Stack Area 에 쌓으면서 객체변수와 참조변수의 instance를  Heap Area 에 저장한다.
  7. main Method에 작성된 코드 대로 작업을 수행해나간다.



2. JVM의 구조

Class Loader

자바는 런타임에 클래스를 처음 실행할 때 해당 클래스를 로드하고 링크하는 특징이 있다.
이 동적 로드를 담당하는 부분이 JVM의 클래스 로더이다.
클래스 로더의 특징은 다음과 같다.

  • 계층 구조 : 클래스 로더 간  슈퍼-서브  관계를 가진 계층 구조로 생성되며 최상위 클래스 로더는 부트스트랩 클래스 로더이다.
  • 위임 모델 : 계층 구조를 바탕으로 클래스 로더 간 로드를 위임하는 구조로 동작한다. 클래스 로드 시 먼저 상위 클래스 로더를 확인 후 상위 클래스 로더에 있다면 해당 클래스를 사용하고, 없다면 로드를 요청받은 클래스 로더 클래스를 새로 로드한다.

클래스 파일은 실행을 위해 기본 클래스 파일(main 메소드를 포함하는 클래스)이 JVM으로 전달된 다음 최종 코드가 실행되기 전 3가지의 단계를 거친다.

Loading

클래스 로더가 .class 파일을 읽고 그 내용에 따라 메소드 영역에 저장
이 때 메소드 영역에 저장하는 데이터는 다음과 같다.

  • FQCN(Fully Quallified Class Name)
  • 클래스 | 인터페이스 | 이넘(Enum)
  • 메소드와 변수

로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여  힙(heap) 영역에 저장한다.

Linking

검증(Verify): .class 파일 형식이 유효한지 체크한다.
준비(Preparation): 클래스 변수(static 변수)와 기본값이 필요한 메모리 준비
Resolve: 심볼릭 메모리 레퍼런스를 메모리 영역에 있는 실제 레퍼런스로 교체한다.

Initialization

static 변수의 값을 할당한다(static block이 있다면 이 때 실행된다.)



3. Runtime Data Area란?

JVM이 OS 위에서 실행되면서 할당받는 메모리 영역이다. Class Loader에서 준비한 데이터들을 보관하는 저장소이다.

1. Method (Static) Area

JVM이 읽어들인 클래스와 인터페이스에 대한 Runtime Constant Pool, 필드, 클래스 변수(Static 변수), 생성자와 메소드를 저장하는 공간이다.

2. Runtime Constant Pool

메소드 영역에 포함되지만 독자적 중요성을 갖는다.
클래스 파일 constant_pool 테이블에 해당하는 영역이다.
클래스와 인터페이스 상수, 메소드와 필드에 대한 모든 레퍼런스를 저장한다.
JVM은 Runtime Constant Pool을 통해 해당 메소드나 필드의 실제 메모리 상 주소를 찾아 참조한다.

※ 메소드 영역/런타임 상수 풀의 사용기간 및 스레드 공유 범위
JVM 시작시 생성
프로그램 종료 시까지
명시적으로 null 선언 시
구성 방식이나 GC 방법은 JVM 벤더마다 다를 수 있다.

3. Heap Area

JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역이다.
New 연산자로 생성된 객체 또는 객체(인스턴스)와 배열을 저장한다.
힙 영역에 생성된 객체와 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 GC의 대상이 된다.

※ 힙 영역의 사용기간 및 스레드 공유 범위
객체가 더 이상 사용되지 않거나 명시적으로 null 선언 시 GC(Garbage Collection) 대상
구성 방식이나 GC 방법은 JVM 벤더마다 다를 수 있다.
모든 스레드에서 공유한다.

4. Stack Area

각 스레드마다 하나씩 존재하며, 스레드가 시작될 때 할당된다.
메소드를 호출할 때마다  프레임(Frame)  추가(push) 하고 메소드가 종료되면 해당 프레임을  제거(pop) 하는 동작을 수행한다.
선입후출(FILO, First In Last Out) 구조로 push와 pop 기능 사용
메소드 호출 시 생성되는 스레드 수행정보를 기록하는 Frame을 저장
메소드 정보, 지역변수, 매개변수, 연산 중 발생하는 임시 데이터 저장
기본(원시)타입 변수는 스택 영역에 직접 값을 가진다.
참조타입 변수는 힙 영역이나 메소드 영역의 객체 주소를 가진다.

5. PC Register

Thread가 생성될 때마다 생기는 공간으로 Thread가 어떠한 명령을 실행하게 될지에 대한 부분을 기록한다.
JVM은 CPU에 직접 Instruction을 수행하지 않고, Stack에서 Operand를 뽑아내 이를 별도의 공간에 저장하는 방식을 취하는데, 이러한 메모리 공간을 PC Register라고 한다.

6. Native Method Stack Area

자바 외 언어로 작성된 네이티브 코드를 위한 Stack이다.
즉, JNI(Java Native Interface)를 통해 호출되는 C/C++ 등의 코드를 수행하기 위한 스택이다.
네이티브 메소드의 매개변수, 지역변수 등을 바이트 코드로 저장한다.

4. JDK, JRE, JVM

JRE(Java Runtime Enviroment): JVM + 라이브러리

  • JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있다.
  • 개발 관련 도구는 포함하지 않는다.(JDK에서 제공)

※ 참고: JDK 11 이후(Java Module 추가)로는 Jlink가 추가되어 JRE가 따로 배포되지 않는다.

JDK(Java Development Kit): JRE + 개발 툴

  • JRE + 개발에 필요한 툴(javac.exe 와 같은 컴파일러를 포함한다)

※ 오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다.

 

0개의 댓글

관련 채용 정보