JVM (Java Virtual Machine)
1. 자바 프로그램이 어떠한 운영체제 상에서도 실행될 수 있도록 하는 도구.
2. Java 프로그램 런타임시 메모리를 관리하고 최적화 하는 것.
[JVM 구성 요소]
#Compiler (컴파일러/ javac)
자바 소스 코드(.java 파일)를 JVM이 이해할 수 있는 바이트코드(.class) 파일로 변환하는 역할.
#Class Loader (클래스 로더)
.java 파일이 컴파일러를 통해 바이트코드(.class)로 변환되면
이 파일들을 메모리가 할당된 Runtime Data Area로 적재하는 역할.
[로딩-링크-초기화] 순서로 진행된다.
A. 로딩
클래스 로더가 바이트코드(.class) 파일을 읽고, 적절한 바이너리 데이터를 만들어 메서드 영역에 저장
B. 링크
컴파일러의 결과물인 바이트코드(.class)를 실행가능한 실행파일(.exe)로 만들기 위해 연결해주는 작업
C. 초기화
static 변수의 값을 할당, 즉 변수에 값이 저장될 때 . static의 블럭이 실행되는 시점.
#Execution Engine(실행 엔진)
클래스 로더에 의해 메모리에 배치된 .class 파일들을
컴퓨터가 이해할 수 있는 기계어로 변경해 명령어 단위로 실행하는 역할.
-기계어로 변경하는 방식-
Interpreter (인터프리터 방식) : 명령어를 한줄씩 번역하여 실행,
JIT (컴파일러 방식) : 바이트코드를 네이티브 코드로 변환
-JVM 메모리 관리 프로세스-
Garbage Collection (가비지 컬렉션) - a.k.a Heap 메모리 관리자 -
자바 프로그램에서 사용되지 않는 Heap 메모리 속 객체들을 지속적으로 관리 및 제거하는 역할
[순서]
참조되지 않은 객체들을 탐색 후 삭제 -> 삭제된 객체의 메모리 반환 -> 힙 메모리 재사용
#Runtime Data Areas (JVM 메모리 영역)
총 5가지 영역으로 나누어짐.
1. 메서드 영역 (Method Area / Static Area)
JVM이 시작될 때 생성되고, 모든 스레드가 공유하는 영역.
JVM이 읽은 코드 중 사용되는 바이트코드(.class)들을 클래스 로더로 읽어
클래스 별로 정적필드(static field), 상수, 메서드 코드, 생성자 코드 등을 저장.
JVM이 동작하고 클래스가 로딩될 때 생성되어 JVM이 종료될 때 까지 유지된다.
2. 힙 영역 (Heap Area)
런타임에 동적으로 할당되는 데이터가 저장되는 영역, 객체(new)나 배열 생성이 해당.
힙 영역은 가비지컬렉터의 관리 대상이 되어 삭제되기도 한다.
** JVM 성능 이슈에서 가장 많이 언급되는 공간.
여기서 생성된 객체와 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
Ex)
(A)Instance (B)instance = new (C)Instance();
(C)는 힙 영역에 저장, (B)참조 변수는 스택 영역에 저장되지만 실제로는 힙 영역의 주소값을 가진다.
즉, 힙의 참조 주소는 스택에 저장되고, 해당 객체를 통해서만 힙 영역에 있는 인스턴스를 핸들할 수 있다
=> 런타임시 할당되며, 주로 객체, 배열이 저장된다.
3. PC 레지스터 (PC Register Area)
스레드가 시작될 때 생성되는 영역.
스레드가 어떤 부분을 무슨 명령으로 실행해야할 지에 대한 기록을 하는 부분으로
현재 수행중인 JVM 명령의 주소를 갖는다.
스레드가 생성되었을 때 메서드 영역, 힙 영역은 모든 스레드가 공유하지만
스택 영역, PC Register, Native Method Stack 영역은 공유되지 않는다.
=> 스레드가 생성될 때마다 생성되는 영역으로 JVM 명령의 주소를 알고 있다.
4. 스택 Area (JVM Stack Area)
메서드 호출 시 프레임(그 메서드만을 위한 공간) 생성하고,
메서드 종료 시 해당 프레임을 제거하는 동작 수행.
프레임 내부에는 '로컬 변수 스택'이 있는데, 기본타입 변수 + 참조타입 변수가 추가되거나 삭제된다.
스택 영역에 변수가 생성되는 시점은 초기화 시점(변수에 값이 저장될 때) 이다.
변수는 선언된 메서드 블록 내에서만 스택에 존재하고, 블럭을 벗어나면 스택에서 제거된다.
즉, 스택 영역은 호출된 메서드의 지역 변수, 매개 변수나 메서드 정보, 임시데이터와
new 연산자 객체 생성시 참조 주소값(힙 주소)도 저장된다.
=> 컴파일시 할당되며, 메소드 호출시 지역변수가 저장된다.
5. 네이티브 메서드 스택 (Native Method Stack Area)
=> 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역.
[실행 과정]
1. 프로그램이 실행시, JVM은 OS로부터 필요로하는 메모리 (Runtime Data Area)를 할당받음.
JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리함.
2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽고, 바이트코드(.class = 클래스 파일)로 변환시킴.
3. 변경된 바이트코드(.class)는 클래스 로더를 통해 JVM 메모리 영역 (Runtime Data Area)으로 적재됨.
4. Execution engine이 JVM 메모리에 적재된 바이트코드(.class) 파일들을 기계어로 변환하여 실행.
5. 이러한 실행 과정 속 JVM은 필요에 따라 스레드 동기화나
가비지 컬렉션를 이용해 힙 영역에 적재된 객체들 중 참조되지 않은 객체를 제거.
[객체 생성의 경우 저장되는 메모리 영역]
클래스(Person) => [클래스 영역]
참조변수 p => [스택 영역]
클래스의 멤버 (필드, 메소드, 이너 클래스) => [힙 메모리]
참조변수 = 객체의 실제 값 X, [힙 영역]에 저장되어 있는 주소 값.
메소드 구현 코드 => [클래스 영역]에 저장되고, 객체 [힙 메모리 영역] 안에서는 그 위치를 가르킨다.
즉 같은 클래스로 만든 모든 객체는 동일한 메소드 값을 공유하기 때문에,
여러 번 같은 메소드를 선언해주는 것이 아니라,
한번만 저장해두고 필요한 경우에만 [클래스 영역]에 정의된 메소드를 찾아 사용할 수 있는 것.
[변수 생성의 경우 저장되는 메모리 영역]
JDK vs JRE
JRE (Java Runtime Environment) = JVM + 표준 클래스 라이브러리
JDK (Java Development Kit) = JRE + 개발에 필요한 도구
'백엔드 기술 > Java' 카테고리의 다른 글
메서드 오버라이딩 VS 오버로딩 (0) | 2023.04.15 |
---|---|
OOP (객체지향 프로그래밍) 이란 ? (0) | 2023.04.15 |
추상 클래스와 인터페이스 차이 (0) | 2023.04.12 |
클래스와 객체의 차이 (0) | 2023.04.12 |
Java 데이터 타입의 기본형 & 참조형 타입 (0) | 2023.04.12 |