Java 메모리 구조

YH·2023년 3월 27일
0

들어가기 전, JVM 이란?

  • Java Virtual Machine의 약자로, 자바 프로그램 실행 환경을 만들어주는 소프트웨어이다.
  • JVM에는 자바 실행 환경(Jave Runtime Environment)가 포함되어 있고, 컴퓨터 OS에 맞는 JRE가 설치되어 있으면 JVM이 설치되어 있다는 뜻임

JVM의 동작 방식

  1. 자바 프로그램을 실행하면 JVM이 OS로부터 메모리를 할당한다.
  2. 자바 컴파일러(javac)가 .java 소스 코드를 바이트코드(.class)로 컴파일한다.
  3. Class Loader를 통해 JVM Runtime Data Area를 로딩한다.
  4. RDA에 로딩 된 바이트 코드(.class)들은 실행 엔진(Execution Engine)을 통해 해석한다.
  5. 해석된 바이트 코드는 RDA의 각 영역에 배치되어 수행하며 이 과정에서 EE에 의해 CG 동작과 쓰레드 동기화가 이루어진다.

Java와 JVM의 특징

  • Java는 플랫폼에 독립적이고, JVM은 플랫폼에 종속적이다.
    • Java는 자바 컴파일러에 의해 컴파일 되면 바이트 코드가 생성되고, 해당 바이트 코드를 플랫폼에 맞게 JVM이 변환해준다.
    • 따라서, 바이트 코드는 어떤 JVM에서도 동작할 수 있기 때문에 플랫폼에 독립적이고, JVM은 플랫폼에 맞는 JVM이 각각 따로 있기 때문에 플랫폼에 종속적인 것이다.

JVM의 구조

  • 클래스 로더(Class Loader)
    -> 런타임 시 동적으로 클래스를 로딩해주는 역할
    -> .java 소스를 컴파일하여 생성된 바이트 코드(.class)를 JVM이 RDA(Runtime Data Area)로 배치시킨다.

  • 실행 엔진(Execution Engine)
    -> 배치된 바이트 코드들을 명령어 단위로 읽어서 실행하는 런타임 모듈이 실행 엔진이다.
    -> 바이트 코드를 읽는 방식에는 Interpreter 방식JIT 컴파일 방식 두 가지가 있다. 두 방식에 대한 내용은 링크에서 설명

  • 가비지 컬렉터(Garbage Collector)
    -> 사용(참조)되지 않는 메모리(객체)를 탐색하여 자동으로 회수해주는 역할
    -> GC가 역할을 하는 시간은 정확히 알 수 없다.
    -> GC가 역할을 수행하는 동안 GC의 쓰레드 외에 나머지 쓰레드들은 일시정지 상태가 된다.
    -> GC에 대한 상세 내용은 링크 참조.

  • 런타임 데이터 영역(Runtime Data Area)
    -> JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.

    • 모든 쓰레드가 공유해서 사용(GC의 대상이 됨)
      • 메소드 영역(Method(=Static) Area)
      • 힙 영역(Heap Area)
    • 쓰레드마다 하나씩 생성
      • 스택 영역(Stack Area)
      • PC Register
      • Native Method Stack

런타임 데이터 영역(Runtime Data Area)

1. 메소드 영역(Method/Static Area)

  • 클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보와 같은 각종 필드 정보들과 메소드 정보, 데이터 Type 정보, Constant Pool, static 변수, final class 등이 생성되는 영역
    • file data(필드 데이터) : 멤버 변수이름, 타입, 접근제어자등의 메타정보
    • method data(메서드 데이터) : 메서드 이름, 리턴타입, 매개변수, 접근제어자등의 메타정보
    • constructor(생성자) : 생성자 메서드에 관한 정보.
    • static 변수(Class 변수) : 모든 객체가 공유할 수 있는 정적 클래스 변수.
    • runtime constant pool (런타임 상수 풀)
  • Method(Static) 영역에 있는 것은 어느 곳에서나 접근 가능
  • Method(Static) 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있다.
    그래서 static 메모리에 있는 데이터들은 프로그램이 종료될 때까지 어디서든 사용이 가능하다.
    그러나 static 데이터를 무분별하게 많이 사용할 경우 메모리 부족 현상이 일어날수 있게 된다.

🔍 Runtime Constant Pool

  • 메소드 영역(Method(Static) Area)에 존재하는 별도의 관리 영역
  • 각 클래스/인터페이스마다 별도의 Constant Pool 테이블이 존재하는데, 클래스를 생성할 때 참조해야 할 정보들을 상수로 가지고 있는 영역임
  • JVM은 Constant Pool을 통해 해당 메소드나 필드의 실제 메모리 상 주소를 찾아 참조함
  • 상수 자료형을 저장하여 참조하고 중복을 막는 역할
  • 상수 풀은 Method Area, 즉 정적 영역에 있는 메모리이기에 GC의 대상이 아님
  • Primarity Type 뿐만 아니라 String 객체, 레퍼런스 타입이 가진 주소 값도 상수 풀로 관리됨

2. 힙 영역(Heap Area)

  • Heap 영역은 위와 같이 3가지 영역으로 나뉨
    • Young Generation 영역은 생성된지 얼마되지 않은 객체가 저장되는 공간
    • 객체가 생성되면 Eden 영역에 할당됨 -> Eden 영역에 일정 데이터가 쌓이게 되면 참조 정도에 따라 Survivor의 빈 공간으로 이동 또는 회수 됨
    • Tenured Generation 영역은 Young Generation 영역이 다 차게 되면 참조 정도에 따라 해당 영역으로 이동 또는 회수 됨
    • Heap 영역의 동작은 GC와 연관되며, 상세 내용은 위의 GC 관련 링크에서 확인
  • 위 내용의 중점은 Heap 영역에서는 메모리 호출이 끝나더라도 남아있게 되고, 더 이상 사용하지 않게되면 GC에 의해 메모리에서 회수된다는 것
  • new 키워드로 생성된 객체와 배열(Reference Type)이 생성되는 영역, 런타임 시 동적으로 할당되어 사용되는 영역
  • Heap 영역에 있는 객체를 가리키는 레퍼런스 변수는 Stack에 적재
  • Heap 영역은 스레드와 상관없이 단 하나의 영역만 존재

3. 스택 영역(Stack Area)

  • 지역변수, 파라미터(매개변수), 리턴 값, 연산에 사용되는 임시 값 등이 생성되는 영역
  • Primitive Type의 데이터에 해당되는 지역변수, 매개 변수 등이 저장 됨
  • 메소드가 호출될 때 스택 영역에 Stack Frame이 생성된 후 메소드를 호출 함
    • Stack Frame이란, 하나의 메소드에 필요한 메모리 덩어리를 말함
    • 하나의 메소드 당 하나의 Stack Frame이 필요함
    • 스택 메모리에 쌓이는 데이터가 위에서 언급한 지역변수, 파라미터, 리턴 값 등이 있다.
  • 메모리 호출 및 할당 후 종료되면 메모리에서 제거 됨
  • 후입선출(Last-In-First-Out)의 특성을 가지며, 호출 범위를 벗어나면 스택에서 제거

4. PC Register 영역

  • 쓰레드가 생성될 때 마다 생성되는 영역으로, 쓰레드마다 하나씩 존재함
  • 현재 쓰레드가 실행되는 부분의 JVM 주소와 명령을 저장하고 있음

5. Native Method Stack 영역

  • 자바 이외의 언어(C, C++, 어셈블리 등)로 작성된 네이티브 코드를 실행할 때 사용되는 메모리 영역



참고 Reference

profile
하루하루 꾸준히 포기하지 말고

0개의 댓글