[JVM] JVM 메모리 영역 상세 - Method, Stack, Heap

itonse·2024년 6월 2일
0

JAVA

목록 보기
18/19

이미지 출처

JVM의 메모리 영역인 런타임 데이터 영역은 크게 Method 영역, Heap 영역, Stack 영역
으로 구분되며, 데이터 타입(자료형)에 따라 각 영역에 나누어 할당됩니다.


이미지 출처

변수의 종류

이미지 출처
public class MemoryEx {

    // 클래스 변수 (Static Variable)
    static int classVariable = 100;

    // 인스턴스 변수 (Instance Variable)
    int instanceVariable;

    public MemoryEx(int value) {   // 매개 변수 (Parameter)
        this.instanceVariable = value;   // 인스턴스 변수에 매개 변수 할당
    }

    public void showVariables(int parameterVariable) {
        // 지역 변수 (Local Variable)
        int localVariable = 10;
    }

    public static void main(String[] args) {
        MemoryEx example = new MemoryEx(50);
        example.showVariables(25);
    }
}

변수들의 생성 시기

  • 클래스 변수: 클래스가 메모리에 올라갈 때
  • 인스턴스 변수: 인스턴스가 생성되었을 때
  • 지역변수, 매개변수: 위치하고 있는 메서드가 수행되었을 때



Method(static) 영역

Java 8 이후) Method 영역과 Metaspace는 어떤 관계일까?

Metaspace는 Java 8에서 PermGen을 대체한 메모리 영역으로, 힙 영역 외부의 네이티브 메모리를 사용합니다. Java 8 이전에는 Method 영역이 PermGen에 속했으나, 이후로는 Metaspace에 속하게 되었습니다.

Metaspace는 클래스 메타데이터를 저장하며, 운영 체제의 네이티브 메모리를 사용하여 메모리 부족 문제를 줄입니다. Java 8 이후로 Method 영역은 Metaspace의 일부로 관리되며, 필요 시 가비지 컬렉션(GC)의 대상이 될 수 있습니다.

Method 영역의 특징

JVM이 동작해서 클래스가 로드될 때 생성 됩니다.

구성 요소

  • 클래스 변수: static 변수
  • 클래스 메타데이터: 클래스명, 부모 클래스명, 인터페이스 정보
  • 메서드 데이터: 메서드명, 반환 타입, 매개변수 타입, 접근 제어자, 바이트코드
  • 필드 데이터: 필드명, 필드 타입, 접근 제어자
  • 상수 풀: 정수, 문자열 리터럴 등의 런타임 상수

Method(static) 영역에 있는 것은 어느곳에서나 접근 가능하다.

Method(Static) 영역의 데이터는 프로그램 시작부터 종료 시까지 메모리에 남아 어디서든 사용 가능합니다. 그러나 static 데이터를 과도하게 사용하면 메모리를 계속 차지해 메모리 부족 현상이 발생할 수 있습니다.

Method 영역의 동작 과정

  1. 클래스 로딩: 클래스 로더가 클래스를 메모리에 로드하면, 클래스의 메타데이터가 Method 영역에 저장됩니다.

  2. 클래스 초기화: 클래스의 정적 초기화 블록이 실행되며, static 필드들이 초기화됩니다.

  3. 클래스 사용: 클래스가 사용되면서 메서드 호출 시 메서드의 바이트코드가 실행되고, 상수 풀에서 상수와 심볼릭 레퍼런스를 참조합니다.

  4. 가비지 컬렉션: 사용되지 않는 클래스 메타데이터는 가비지 컬렉터에 의해 제거됩니다.

Method 영역(Metaspace)의 메모리 관리

  • 힙 메모리 외부의 네이티브 메모리 사용
  • 필요에 따라 Metaspace 크기 자동 확장/축소
  • 클래스 언로드: 사용되지 않는 클래스 메타데이터 해제
  • 메모리 관리 옵션: -XX:MaxMetaspaceSize, -XX:MetaspaceSize 등으로 크기 및 동작 제어



Stack 영역

Stack 영역의 특징

메서드 내에서 정의하는 기본 자료형에 해당되는 지역변수의 데이터 값이 저장되는 공간

구성 요소

  • 스택 프레임: 스택의 기본 단위로, 각 메서드 호출은 새로운 스택 프레임을 생성한다. 각 프레임은
    다음을 포함한다.
    • 메서드의 매개변수, 지역변수, 리턴값, 프레임 데이터(메서드의 호출자, 복귀 주소)

스택은 후입선출(LIFO) 방식으로 작동합니다. 즉, 마지막에 추가된 메서드 호출이 먼저 제거됩니다.

메모리 관리

JVM이 자동으로 관리: 메서드 호출 시 스택 프레임이 추가되고, 메서드 종료 시 제거된다.

메모리 제한: 스택의 크기는 제한되어 있으며,무한 재귀 호출 등으로 인해 Stack Overflow가 발생할 수 있다.

Stack 영역의 동작 과정

  1. 메서드 호출 시 스택 프레임 생성: 메서드가 호출될 때마다 새로운 스택 프레임이 생성되어 스택의 맨 위에 추가됩니다.

  2. 메서드 종료 시 스택 프레임 제거: 메서드 실행이 끝나면 해당 스택 프레임은 스택에서 제거됩니다.



Heap 영역

Heap 영역의 특징

객체와 배열이 동적으로 할당되는 영역입니다.(프로그램 실행 중에 크기가 변경될 수 있다)

힙 메모리의 크기는 JVM 커맨드 라인 옵션(-Xmx: 최대 힙 크기, -Xms: 초기 힙 크기)을 사용하여 설정할 수 있습니다.

Heap 영역은 Stack 영역과 달리 호출이 끝나더라도 메모리가 삭제되지 않고 유지됩니다.
하지만 어떤 참조 변수도 Heap 영역의 인스턴스를 참조하지 않게 되면 GC(가비지 컬렉터)에 의해 메모리에서 제거됩니다.

스택에 비해 상대적으로 접근 속도가 느리며, 메모리 단편화가 발생할 수 있습니다.

Heap 영역 구조

1. Young Generation

객체가 처음 생성되는 영역으로, 객체의 생명 주기가 짧은 경우가 많습니다.

  • 구조
    • Eden 영역: 새로 생성된 객체가 할당되는 곳입니다. 대부분의 객체가 이곳에 생성되며, 가비지 컬렉션이 자주 발생합니다.
    • Survivor 영역: Eden 영역에서 살아남은 객체들이 이동되는 두 개의 영역(Survivor From, Survivor To)입니다. 각각의 GC 사이클 동안 객체는 두 Survivor 영역 사이를 이동하며 살아남은 객체는 결국 Old Generation으로 이동합니다.

2. Old Generation

Young Generation를 지나 살아남은 객체들이 존재하는 영역으로, 객체의 생명 주기가 긴 경우가 많습니다.



ref.
그림으로 보는 자바 코드의 메모리 영역(스택 & 힙) (좋은 레퍼런스)
[Java] Java 메모리 영역(stack, heap, static), JVM, JAVA 변수 종류

0개의 댓글

관련 채용 정보