JVM 이해하기
1. 자바, JVM, JDK 그리고 JRE

JVM (Java Virtual Machine)
- 자바 가상 머신으로 자바 바이트코드를 OS에 특화된 코드로 변환
- 바이트 코드를 실행하는 표준(JVM 자체는 표준)이자 구현체(특정 밴더가 구현한 JVM)
JRE (Java Runtime Environment)
- 자바 애플리케이션을 실행할 수 있도록 수어된 배포판.
- JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있음.
- 개발 관련 도구는 JDK에서 제공
JDK (Java Development Kit)
- JRE + 개발에 필요한 툴
- 소스 코드를 작성할 때 사용하는 자바 언어는 플랫폼에 독립적
- 오라클은 자바 11부터 JDK만 제공하며 JRE를 따로 제공하지 않는다.
자바
- 프로그래밍 언어
- JDK에 들어있는 자바 컴파일러를 사용하여 바이트코드로 컴파일 할 수 있다.
- Oracle JDK 11버전부터 상용으로 사용할 때 유료 (Open JDK무료) 벤더사마다 다르다
2. JVM 구조

클래스 로더 시스템
- 로딩 : 클래스 읽어오는 과정
- 링크 : 레퍼런스를 연결하는 과정
- 초기화 : static 값들 초기화
메모리
- 메소드 영역 : 클래스 수준의 정보를 저장(클래스이름, 부모 클래스 이름, 메소드, 변수) 저장. 공유자원
- 힙 영역 : 객체를 저장. 공유자원
- 스택 영역 : Thread마다 Runtime 스택을 만들고, 그 안에 Method 호출을 Stack프레임이라 부르는 블럭으로 쌓는다. 쓰레드 종료하면 런타임 스택도 사라진다.
- PC(Program Counter) 레지스터 : Thread마다 Thread내 현재 실행할 스택 프레임을 가리키는 포인터가 생성된다.
- 네이티브 메소드 스택 : 예) native 키워드가 붙어있는…
스택, PC, native method stack은 특정 Thread에 국한 되어있다.
실행엔진
- 인터프리터 : 바이트 코드를 한줄 씩 실행
- JIT 컴파일러 : 인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둔다. 그 다음 인터프리터는 네이티브 코드로 컴파일 된 코드를 바로 사용한다
- GC(Garbage Collector) : 더 이상 참조되지 않는 객체를 모아서 정리한다.
JNI(Java Native Interface)
- 자바 애플리케이션에서 C, C++, 어셈블리로 작성된 함수를 사용할 수 있는 방법 제공
- Native 키워드를 사용한 메소드 호출
네이티브 메소드 라이브러리
- C, C++로 작성 된 라이브러리
3. 클래스 로더

클래스 로더
- 로딩, 링크, 초기화 순으로 진행
- 로딩
- 클래스 로더가 .class 파일을 읽고 메모리 영역 내 메소드 영역에 저장
- 이때 메소드 영역에 저장하는 데이터 FQCN, Class / Interface / Enum , 메소드와 변수
- 로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여 “heap” 영역에 저장
- 링크
- Verity, Prepare, Resolve(optional) 세 단계로 나뉘어져 있다.
- 검증 : .class파일 형식이 유효한지 체크한다.
- Preparation : 클래스 변수(static 변수)와 기본값에 필요한 메모리
- Resolve : 심볼릭 메모리 레퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체한다.
- 초기화
- static 변수의 값을 할당한다. (static 블럭이 있다면 이 때 실행된다.)
- 클래스 로더는 계층 구조로 이루어져 있으면 기본적으로 세가지 클래스 로더가 제공된다.
- 부트 스트랩 클래스 로더 - JAVA_HOME\lib에 있는 코어 자바 API를 제공한다.
- 플랫폼 클래스 로더 - JAVA_HOME\lib\ext 폴더 또는 java.ext.dirs 시스템 변수에 해당하는 위치에 있는 클래스를 읽는다.
- 애플리케이션 클래스로더 - application ClassPath(애플리에키션 실행할 때 주는 -classpath옵션 또는 java.class.path 환경 변수의 값에 해당하는 위치)에서 클래스를 읽는다.