Java Virtual Machine ?
JVM이란?
Java코드 또는 애플리케이션을 구동하기 위한 런타임 환경을 제공하는 엔진이다.
Java 바이트 코드(.class) 를 기계 언어(OS에 특화된 언어)로 변환 한다.
JRE (Java Runtime Environment)
- JVM + 라이브러리
- 자바 애플리케이션을 실행할 수 있도록 구성된 배포판
- JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있다.
- 개발 관련 도구는 포함하지 않는다. ( JDK에서 제공 )
JDK (Java Development Kit)
- JRE + 개발에 필요한 툴
- 소스 코드를 작성할 때 사용 하는 자바 언어는 플랫폼에 독립적
- 오라클 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다.
- 자바 컴파일러도 JDK에 해당
자바 유료화 ? 오라클에서 만든 Oracle JDK 11 버전 부터 상용으로 사용할 때 유료
11버전 하위 이거나 Open JDK 이거나 Amazon JDK (Corretto) 는 무료이다
JVM의 작동 방식
Java 코드가 바이트 코드로 컴파일 된다. (바이트 코드는 호스트시스템과 JAVA 소스 사이의 중간 언어이다)Java의 JVM은 메모리 공간 할당을 담당한다.
JVM 아키텍쳐
3가지 서브 시스템으로 구분할 수 있다.
1. 클래스 로더 시스템
- Java의 동적 클래스 로딩 기능은 Class Loader System에서 처리합니다.
Loading : 클래스 읽어오는 과정
- 클래스 로더가 .class 파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 "메소드"영역에 저장
- 이 때 메소드 영역에 저장하는 데이터
- FQCN
- 클래스 , 인터페이스 , 이늄
- 메소드 와 변수
- 로딩이 끝나면 해당 클래스 타입의 Class객체를 생성하여 "힙" 영역에 저장
- 이 때 메소드 영역에 저장하는 데이터
- 클래스 로더는 계층 구조로 이뤄져 있으며 , 기본적으로 세가지 클래스 로더가 제공된다.
- BootStrap ClassLoader
- JAVA_HOME\lib 에 있는 코어 자바 API를 제공한다.
- 클래스 로더 중 가장 높은 우선순위가 부여된다.
- Extension ClassLoader(플랫폼 클래스로더)
- JAVA_HOME\lib\ext 폴더 또는 java.ext.dirs 시스템 변수에 해당하는 위치에 있는 클래스를 읽는다.
- Application ClassLoader
- 애플리케이션 클래스패스 (애플리케이션 실행할 때 주는 -classpath 옵션 또는 java.class.path 환경 변수의 값에 해당하는 위치) 에서 클래스를 읽는다.
- BootStrap ClassLoader
public class App {
public static void main(String[] args) {
ClassLoader classLoader = App.class.getClassLoader();
System.out.println(classLoader);
System.out.println(classLoader.getParent());
System.out.println(classLoader.getParent().getParent());
// 클래스 로더는 계층형 구조
// 출력
//sun.misc.Launcher$AppClassLoader@18b4aac2
//sun.misc.Launcher$ExtClassLoader@1540e19d
//null - native코드로 구현되어 있기 때문에 출력할 수 없다.
}
}
Linking : 레퍼런스를 연결하는 과정
- Verify (확인)
- .class 파일 형식이 유효한지 체크한다.
- 바이트 코드 검증기는 생성된 바이트 코드가 적절한지 여부를 확인 한다.
- 확인이 실패하면 확인 오류가 발생한다.
- Prepare(준비)
- 모든 정적 변수(static 변수) 에 대해 메모리가 할당 되고 기본값으로 할당 된다.
- Resolve(해결)
- All symbolic memory references are replaced with the original references from Method Area.
- 기호 참조를 유형에서 직접 참조로 변환한다.
Initialization : static 값들 초기화 및 변수에 할당
- static 변수의 값 할당 , static 블록이 있다면 이 때 실행된다.
- 클래스 로딩의 마지막 단계
- 여기서 모든 정적 변수(Static Keyword in Java)는 원래 값으로 할당되고 정적 블록(Java Static Import)이 실행된다.
2. 런타임(실행) 데이터 영역 ★
- 런타임 데이터 영역은 5개의 주요 구성 요소로 나뉜다.
Method Area(메소드 영역) ★
- 클래스 수준의 정보 (클래스 이름 , 부모 클래스 이름 , 메소드 , 변수) 저장
- JVM 인스턴스 내에서 로드된 Types에 대한 정보 메소드 영역이라는 메모리의 논리적 영역에 저장된다.
- 정적 변수를 포함하여 모든 클래스 수준 데이터가 여기에 저장 된다.
- JVM당 하나의 메소드 영역만 있으며 공유 자원이다.
Heap Area(힙 영역)
- 모든 개체와 해당 인스턴스 변수 및 배열이 여기에 저장된다.
- JVM당 하나의 힙 영역만 있다.
- 메소드 및 힙 영역은 멀티 스레드에 대한 메모리를 공유하므로 저장된 데이터는 스레드로 부터 안전하지 않다.
- Young Generation (만들어 지지 얼마 되지않은 객체들)
- Eden
- 2개의 Survivor Space
- Old Generation (오래된 객체들)
- PermGen (JAVA8에서 사라짐 , Metaspace로 변경)
Stack Area(스택 영역)
- 모든 스레드 마다 런타임 스택을 만들고 , 그 안에 메소드 호출을 스택 프레임 (메서드 콜)이라 부르는 블럭으로 쌓는다.
- 스레드 종료하면 런타임 스택도 사라진다.
- 에러 메세지의 쌓여있는 예외 정보들이 스택 프레임(메서드 콜) 이다.
- 모든 지역 변수는 스택 메모리에 생성된다.
- 스택 영역은 공유 자원이 아니므로 스레드로 부터 안전하다.
- 스택프레임(Stack Frame)은 아래 3가지 항목으로 나뉜다.
- Local Varibale(로컬 변수)
- 메소드의 지역 변수들을 갖는다.
- Operand stack(피연산자 스택)
- 메소드 내 계산을 위한 작업 공간이다.
- Frame data(프레임 데이터)
- Local Varibale(로컬 변수)
PC(Program Counter) Registers
- 각 스레드에는 별도의 PC레지스터가 있으며 , 명령이 실행되면 현재 실행중인 명령의 주소를 유지하기 위해 PC레지스터가 다음 명령으로 업데이트 된다.
- 스레드 마다 스레드 내 현재 실행할 instruction의 위치를 가리키는 포인터가 생성된다.
Native Method Stacks
3. 실행 엔진
- 클래스 로더가 런타임 데이터 영역에 바이트 코드를 할당하면 실행 엔진(Execution Engine)에 의해 실행된다.
- 자바 바이트 코드는 기계가 바로 수행할 수 있는 언어가 아니다.
- 실행 엔진은 바이트 코드를 실제로 JVM내부에서 기계가 실행 할 수 있는 형태로 변경 하게 되는데 이 때 2가지 방식을 사용한다.
Interpreter(인터프리터)
- 자바 바이트 코드를 명령어 단위로 읽어서 실행
- 한 줄 단위로 받아들여 실행 하기 때문에 느리다.
JIT Compiler(Just-In-Time)
- 인터프리터 방식의 단점을 보완하기 위해 도입되었다.
- 실행엔진은 바이트 코드를 변환할 때 인터프리터를 사용하지만 반복된 코드를 찾으면 전체 바이트 코드를 컴파일 하고 네이티브 코드로 변경하는 JIT를 사용한다.
- 이 네이티브 코드는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 빠르게 수행 된다.
- JIT 컴파일러가 컴파일 하는 과정은 바이트 코드를 인터프리팅하는 것 보다 훨씬 오래 걸리므로 한 번만 실행되는 코드라면 컴파일 하지않고 인터프리팅 하는 것이 유리하다.
- JIT 컴파일러를 사용하는 JVM들은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하여 일정 수가 넘을 때에만 실행한다.
Garbage Collector
- 참조되지 않는 객체를 수집하고 제거한다.
- System.gc()로 호출할 수는 있지만 실행이 보장되지는 않는다.
JNI(Java Native Interface)
- 자바 애플리케이션에서 C , C++ , 어셈블리로 작성된 함수를 사용할 수 있는 방법 제공
- Native 키워드를 사용한 메소드 호출
- Native Method Libraries와 상호 작용하며 실행 엔진에 필요한 Native Libraries를 제공한다.
Native Method Libraries
- C , C++로 작성된 라이브러리
- 실행 엔진에 필요한 Native Libraries의 모음이다.
출처
Java Virtual Machine's Internal Architecture
Chapter 5 of Inside the Java Virtual Machine The Java Virtual Machine by Bill Venners Page 1 of 13 >> Advertisement The previous four chapters of this book gave a broad overview of Java's architecture. They showed how the Java virtual machine fits into
www.artima.com
The JVM Architecture Explained - DZone Java
This post explores the JVM architecture, what it is, how it operates, why it's useful, and presents a helpful diagram that highlights major JVM functionalities.
dzone.com
더 자바, 코드를 조작하는 다양한 방법 - 인프런
여러분이 사용하고 있는 많은 자바 라이브러리와 프레임워크가 "어떻게" 이런 기능을 제공할 지 궁금한적 있으신가요? 이번 강좌를 통해 자바가 제공하는 다양한 코드 또는 객체를 조작하는 방
www.inflearn.com