JDK, JRE, JVM의 관계를 포함한 전체 자바
1. JDK (Java Development Kit)
- 정의: 자바 개발 키트로, 자바 애플리케이션을 개발하고 컴파일하기 위한 도구와 라이브러리들을 포함하고 있습니다.
- 구성 요소:
- JRE: 자바 애플리케이션을 실행하기 위한 런타임 환경.
- javac: 자바 컴파일러로, 자바 소스 코드를 바이트코드(.class 파일)로 컴파일합니다.
- javadoc: 자바 문서 생성기.
- 기타 개발 도구들 (예: JAR 도구, 디버거 등).
- 용도: 자바 애플리케이션을 작성, 컴파일, 디버그, 실행하는 데 사용됩니다.
2. JRE (Java Runtime Environment)
- 정의: 자바 런타임 환경으로, 자바 애플리케이션을 실행하기 위한 환경입니다.
- 구성 요소:
- JVM: 자바 바이트코드를 실행하는 가상 머신.
- 자바 클래스 라이브러리: 자바 애플리케이션이 사용할 수 있는 표준 클래스 라이브러리.
- 자바 클래스 로더: 클래스 파일을 메모리로 로드하는 역할.
- 용도: 이미 컴파일된 자바 애플리케이션을 실행하는 데 사용됩니다. 개발 도구는 포함하지 않습니다.
3. JVM (Java Virtual Machine)
- 정의: 자바 바이트코드를 실행하기 위한 가상 머신입니다.
- 구성 요소:
- 실행 엔진: 자바 바이트코드를 기계어로 변환하여 실행합니다.
- 메모리 관리: 힙, 스택 등의 메모리를 관리합니다.
- 가비지 컬렉터: 사용되지 않는 메모리를 자동으로 해제합니다.
- 용도: 자바 바이트코드를 실제로 실행하며, 플랫폼 독립적으로 자바 애플리케이션이 실행될 수 있도록 해줍니다.
관계 요약:
- JDK는 JRE를 포함하고, JRE는 JVM을 포함합니다.
- JDK는 자바 애플리케이션을 개발하고 실행할 수 있는 전체 도구 세트입니다.
- JRE는 자바 애플리케이션을 실행하기 위한 환경으로, 개발 도구는 포함하지 않고 실행에 필요한 구성 요소들로 이루어져 있습니다.
- JVM은 자바 바이트코드를 실제로 실행하는 가상 머신입니다.
--------------------------
| 자바 애플리케이션 | .java 파일(소스 코드) -> .class 파일(바이트코드)
--------------------------
| JDK | Java Development Kit
| --------------------- | - javac, javadoc 등 개발 도구
| | JRE | |
| | Java Runtime Environment | - 자바 클래스 라이브러리
| | ------------------- | - 자바 클래스 로더
| | | JVM | |
| | | Java Virtual Machine | - 실행 엔진, 메모리 관리, 가비지 컬렉터
| | ------------------- |
| --------------------- |
--------------------------
| 운영체제 | 예: Windows, Linux, macOS
--------------------------
JAR 파일 빌드 과정:
- 소스 코드 작성 (.java 파일):
- 개발자는 자바 소스 코드를 작성합니다.
- 컴파일 (javac 사용):
- JDK에 포함된 javac 컴파일러를 사용하여 소스 코드를 바이트코드(.class 파일)로 컴파일합니다.
- 예: javac MyClass.java 명령어를 통해 .java 파일을 .class 파일로 변환합니다.
- JAR 파일 생성 (jar 도구 사용):
- JDK에 포함된 jar 도구를 사용하여 여러 개의 .class 파일과 기타 리소스 파일들을 하나의 JAR(Java ARchive) 파일로 묶습니다.
- 예: jar cf myapp.jar *.class 명령어를 통해 JAR 파일을 생성합니다.
Method 영역 (메소드 영역)
- 정의: JVM이 시작될 때 생성되는 메모리 영역으로, 모든 스레드가 공유합니다.
- 저장 내용:
- 클래스 정보: 클래스 이름, 부모 클래스 이름, 메서드와 변수 정보 등.
- 메서드 정보: 메서드의 바이트코드, 접근 제어자, 리턴 타입, 매개변수 목록 등.
- 변수 정보: 클래스 변수(static 변수)와 같은 정보.
- 특징:
- 메소드 영역은 JVM 내에서 단 한 번만 로드되며, 모든 스레드가 이 영역을 공유합니다.
- 여기 저장된 데이터는 런타임 동안 변경되지 않습니다.
Heap 영역 (힙 영역)
- 정의: 자바 애플리케이션에서 동적으로 생성된 객체가 저장되는 메모리 영역입니다.
- 저장 내용:
- 동적으로 생성된 객체: new 연산자를 통해 생성된 객체와 배열 등이 포함됩니다.
- 특징:
- 힙 영역은 GC(가비지 컬렉터)의 대상이 되는 공간입니다. 즉, 더 이상 참조되지 않는 객체들을 찾아내어 메모리를 해제합니다.
- 힙 영역은 Young Generation과 Old Generation으로 나뉘어 관리됩니다.
효율적인 GC를 위해서 5가지 영역으로 나누어진다.
힙 메모리는 자바 애플리케이션에서 생성된 객체들을 저장하는 공간입니다. 이 힙 메모리는 여러 세대로 나뉘어 관리되며, 각각의 세대는 특정 목적을 가지고 있습니다. 다음은 이 다이어그램에 대한 설명입니다:
1. Heap (힙)
- Heap: 자바 애플리케이션이 사용하는 모든 객체를 저장하는 메모리 공간입니다. 힙 메모리는 크게 Young Generation, Old Generation, Permanent Generation으로 나뉩니다.
2. Young Generation (젊은 세대)
- Eden Space: 새로운 객체가 처음으로 할당되는 영역입니다. 대부분의 객체가 여기서 생성되고, 많은 객체들이 금방 가비지 컬렉션됩니다.
- Survivor Space (S0, S1): Eden Space에서 가비지 컬렉션 후 살아남은 객체들이 이동하는 영역입니다. 두 개의 Survivor Space가 있으며, 가비지 컬렉션 과정에서 서로 간에 객체를 복사하며 살아남은 객체들을 보관합니다.
3. Old Generation (노년 세대)
- Tenured Generation: Young Generation을 여러 번 거쳐 살아남은 객체들이 이동하는 영역입니다. 이곳의 객체들은 비교적 오래 생존하는 객체들입니다. 이 영역에서 가비지 컬렉션이 발생하면 더 많은 시간이 걸리기 때문에 이 영역의 가비지 컬렉션은 빈번하지 않습니다.
4. Permanent Generation (영구 세대)
- Permanent Generation: 자바 런타임 환경 자체의 메타데이터(클래스 정보, 메서드 정보 등)를 저장하는 영역입니다. 이 영역은 자주 변경되지 않으며, JVM에 의해 관리됩니다.
Stack 영역 (스택 영역)
- 정의: 각 스레드마다 별도로 존재하는 메모리 영역으로, 메서드 호출 시 생성되는 프레임들이 저장됩니다.
- 저장 내용:
- 지역 변수: 메서드 내에서 선언된 변수들.
- 메서드 매개변수: 메서드 호출 시 전달되는 인자들.
- 임시 변수: 메서드 실행 중 임시로 사용되는 변수들.
- 메서드 호출 정보: 메서드 호출 시의 상태(프로그램 카운터, 호출된 메서드, 복귀 주소 등).
- 특징:
- 스택은 Last In First Out (LIFO) 방식으로 동작합니다.
- 메서드가 호출될 때마다 스택 프레임이 생성되며, 메서드 호출이 종료되면 해당 스택 프레임이 제거됩니다.
- 각 스레드는 자신만의 스택을 가지고 있으며, 스택 영역은 스레드 간에 공유되지 않습니다.
// Method 영역: Person 클래스 정보, 생성자, 메서드 정의가 저장됨
class Person {
// 힙 영역: 인스턴스 변수
String name;
int age;
// Method 영역: 생성자 정의
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Method 영역: 메서드 정의
public void display() {
System.out.println("Name: " + name + ", Age: " + age);
}
}
public class Main {
public static void main(String[] args) {
// Method 영역: main 메서드가 로드됨
// 스택 영역: main 메서드의 프레임이 생성됨
// 스택 영역: 참조 변수 p가 생성됨
// 힙 영역: new Person("이정록", 26) 객체가 생성됨
// p는 힙 영역의 Person 객체를 참조함
Person p = new Person("이정록", 26);
// 스택 영역: display 메서드 호출 시 display 메서드의 프레임이 생성됨
// display 메서드의 지역 변수 name과 age는 힙 영역의 Person 객체의 변수 값을 참조함
p.display(); // Name: 이정록, Age: 26 출력
}
}
PC(Program Counter) Register는 각 스레드마다 별도로 생성되며, 현재 수행 중인 JVM 명령어의 주소를 저장하는 공간입니다. 각 스레드가 어떤 명령어를 수행 중인지 추적하는 역할을 합니다.
네이티브 메서드 스택은 JVM에서 자바 외부의 네이티브 코드를 실행하기 위해 사용되는 스택입니다. 이는 주로 C나 C++로 작성된 메서드를 호출할 때 사용됩니다.