본문 바로가기

카테고리 없음

[Java] - 자바 메모리

 

JDK, JRE, JVM의 관계를 포함한 전체 자바

 

1. JDK (Java Development Kit)

  • 정의: 자바 개발 키트로, 자바 애플리케이션을 개발하고 컴파일하기 위한 도구와 라이브러리들을 포함하고 있습니다.
  • 구성 요소:
    • JRE: 자바 애플리케이션을 실행하기 위한 런타임 환경.
    • javac: 자바 컴파일러로, 자바 소스 코드를 바이트코드(.class 파일)로 컴파일합니다.
    • javadoc: 자바 문서 생성기.
    • 기타 개발 도구들 (예: JAR 도구, 디버거 등).
  • 용도: 자바 애플리케이션을 작성, 컴파일, 디버그, 실행하는 데 사용됩니다.

2. JRE (Java Runtime Environment)

  • 정의: 자바 런타임 환경으로, 자바 애플리케이션을 실행하기 위한 환경입니다.
  • 구성 요소:
    • JVM: 자바 바이트코드를 실행하는 가상 머신.
    • 자바 클래스 라이브러리: 자바 애플리케이션이 사용할 수 있는 표준 클래스 라이브러리.
    • 자바 클래스 로더: 클래스 파일을 메모리로 로드하는 역할.
  • 용도: 이미 컴파일된 자바 애플리케이션을 실행하는 데 사용됩니다. 개발 도구는 포함하지 않습니다.

3. JVM (Java Virtual Machine)

  • 정의: 자바 바이트코드를 실행하기 위한 가상 머신입니다.
  • 구성 요소:
    • 실행 엔진: 자바 바이트코드를 기계어로 변환하여 실행합니다.
    • 메모리 관리: 힙, 스택 등의 메모리를 관리합니다.
    • 가비지 컬렉터: 사용되지 않는 메모리를 자동으로 해제합니다.
  • 용도: 자바 바이트코드를 실제로 실행하며, 플랫폼 독립적으로 자바 애플리케이션이 실행될 수 있도록 해줍니다.

관계 요약:

  • JDKJRE를 포함하고, JREJVM을 포함합니다.
  • JDK는 자바 애플리케이션을 개발하고 실행할 수 있는 전체 도구 세트입니다.
  • JRE는 자바 애플리케이션을 실행하기 위한 환경으로, 개발 도구는 포함하지 않고 실행에 필요한 구성 요소들로 이루어져 있습니다.
  • JVM은 자바 바이트코드를 실제로 실행하는 가상 머신입니다.

 

--------------------------
|   자바 애플리케이션     |  .java 파일(소스 코드) -> .class 파일(바이트코드)
--------------------------
|           JDK           |  Java Development Kit
|  ---------------------  |  - javac, javadoc 등 개발 도구
|  |        JRE        |  |  
|  | Java Runtime Environment |  - 자바 클래스 라이브러리
|  |  -------------------  |  - 자바 클래스 로더
|  |  |      JVM       |  |  
|  |  | Java Virtual Machine |  - 실행 엔진, 메모리 관리, 가비지 컬렉터
|  |  -------------------  |  
|  ---------------------  |
--------------------------
|        운영체제         |  예: Windows, Linux, macOS
--------------------------

 

JAR 파일 빌드 과정:

  1. 소스 코드 작성 (.java 파일):
    • 개발자는 자바 소스 코드를 작성합니다.
  2. 컴파일 (javac 사용):
    • JDK에 포함된 javac 컴파일러를 사용하여 소스 코드를 바이트코드(.class 파일)로 컴파일합니다.
    • 예: javac MyClass.java 명령어를 통해 .java 파일을 .class 파일로 변환합니다.
  3. 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++로 작성된 메서드를 호출할 때 사용됩니다.