런타임 데이터 영역이란?

OS에서 JVM에 할당해준 메모리 영역을 Runtime Data Area,

런타임 데이터 영역이라 한다.

structure.png

런타임 데이터 영역은 그림 같이

  1. 스택
  2. PC
  3. 메소드
  4. 네이티브 메소드 스택

5가지 영역으로 나눌 수 있다.

스택

쓰레드마다 런타임 스택이 생성되며

자바에서 메서드를 호출할 때 메서드의 프레임이 저장되는 영역

그리고 그 프레임 안에는 지역변수, 인자값, 리턴값 등이 저장된다.

메서드 호출 하나 하나마다 새 프레임이 생성되어 스택에 쌓이고

메서드 호출이 정상적으로 종료되거나 예외가 발생시 프레임은 스택에서 빠져나와 소멸된다.

쓰레드가 종료시 쓰레드가 가지고 있는 스택도 제거된다.

스택에도 직접적으로 저장되는 값이 있고 힙영역에 저장되며 레퍼런스만 저장하는 값이 있는데

기본 자료형, Primitive Type 의 경우 스택 영역에 저장되고

기본 자료형을 제외한 타입의 경우

힙 영역에 저장되고 스택 영역의 레퍼런스값을 통해 연결된다.

PC Resisters

쓰레드가 생성될 때마다 생성되어, 각 쓰레드마다 존재함.

쓰레드가 생성될 때마다 그 쓰레드가 어떠한 명령을 실행하게 될지에 대한 부분을 기록하는 메모리 공간을 말한다.

JVM은 Stacks-Base 방식으로 작동한다.

JVM은 CPU에 직접 명령을 수행하지 않고 Stack에서 Operand를 뽑아내 이를 별도의 메모리 공간에 저장하는 방식을 취하는데, 이러한 메모리 공간을 PC Registers라고 한다.

연산을 위해 필요한 피연산자를 임시로 저장하기 위한 용도로 사용한다.


모든 스레드 간에 공유되는 영역이며

런타임 중에 생성된 개체, 클래스의 메타 데이터, 배열 등이 포함됨.

JVM이 종료되면 소멸되어 OS에 반환된다.

실행시 특정 플래그를 사용하여 JVM의 힙 요구량을 제어할 수 있으며,

GC, Garbage Collector 에 의해 이 공간이 관리되고 필요없어진 리소스를 정리하여 공간을 정리한다.

힙::힙의 구조

stack.png

위에 그림은 일반적으로 알려진 힙의 구조다.

크게 Young GenerationOld Generation 영역으로 나뉘며

Young Generation

  1. Eden
  2. Survivor

영역으로 나뉘게 된다.

힙::Eden

객체가 최초로 Heap 영역에 할당되는 장소

이 영역이 가득 찰시에

  1. 새로 할당할 객체의 참조여부를 확인
  2. Live Object, 즉 사용중인 객체를 Suvivor 영역으로 넘김
  3. 참조가 사라진 Garbage Object의 경우 그대로 둠
  4. Eden 영역을 모두 청소

힙::Survivor

Survivor0Survivor1 로 구성되는 영역

Eden 영역에 살아 남은 객체들이 잠시 머무르는 곳
Live Object 사용중인 객체들은 하나의 Survivor 영역만 사용하게 되며
이러한 전반적인 과정을 Minor GC라고 한다.

힙::Old Generation

Old Generation은 새로 Heap에 할당된 객체가 들어오는 것이 아닌, Survivor 영역에서 살아남아 오랫동안 참조 되었고 앞으로도 사용될 확률이 높은 객체들을 저장하는 영역이다.

이러한 Promotion 과정 중 Old Generation의 메모리가 충분하지 않으면 해당 영역에서 GC가 발생하는데 이를 Major GC라고 한다.

힙::Permanent

Permanent 영역은 보통 Class Meta 정보나 메소드의 메타 정보,
static 변수와 상수 정보들이 저장되는 공간으로 흔히 메타데이터 저장 영역이라고 한다.

이 영역은 JAVA8 부터 Native Memory 영역으로 이동하였다.

기존의 Permanent 영역 존재하는 static objectHeap 영역으로 옮겨졌다.


메소드 영역

메서드 영역에서는 런타임 상수풀과 메서드 데이터 내용, 생성자 및 메서드의 코드 내용을 저장.

즉, 코드 레벨에 클레스 수준의 정보를 저장한다.

여기에 클래스 변수가 저장되며

해당 클래스가 코드에서 맨 처음 사용될 때 메서드 영역에 로딩되며

추가로 이때 클래스의 static 블록이 존재한다면 단 한번 실행된다.

전역 변수 및 statc 변수 가 프로그램 종료시 까지 어디서든 사용 가능한 이유다.

메소드 영역에 저장되는 데이터는

  • Type Information
    타입 정보
  • Runtime Constant Pool
    런타임 상수 풀
  • Field Information
    필드 정보
  • Method Information
    메서드 정보
  • Class Variable
    클래스 변수

와 같으며 해당 내용에 대해 좀 더 알아보자면

메소드 영역::Type Information

  • Type의 전체 이름
  • Type의 직계 하위 클래스 전체 이름
  • Type 클래스 / 인터페이스 여부
  • Type의 접근 제어자
    public / abstract / final
  • 연관된 인터페이스 이름 리스트

메소드 영역::Runtime Constant Pool

  • 타입의 모든 상수 정보를 가지고 있다.
  • Type, Field, Method의 모든 Symbolic Reference 정보
  • Constant PoolEntry는 인덱스 번호를 통해 접근
  • 객체의 접근 등 모든 참조를 위한 핵심 요소

메소드 영역::Field Information

  • 필드 타입
  • 필드의 접근 제어자 public / private / protected / static / final / volatile / transient

메소드 영역::Method Information

  • Constructor, 생성자를 포함한 모든 메소드
  • 메소드 이름
  • 메소드 반환 타입
  • 메소드 파라미터 수와 타입
  • 메소드의 접근 제어자
  • 메소드 구현 부분이 있을 경우
  • 메소드의 바이트 코드
  • 메소드의 스택 프레임의 Operand StackLocal variable section의 크기
  • Exception Table

메소드 영역::Class Variable

  • Class 변수는 static 키워드로 선언된 변수를 의미
  • 모든 인스턴스에 공유 되며 인스턴스가 없어도 직접 접근이 가능하다.
  • 변수는 인스턴스의 것이 아니라 클래스에 속하게 된다.
  • 클래스를 사용 하기 이전에 이 변수들은 미리 메모리를 할당 받은 상태가 된다.
  • final class 변수는 상수로 치환 되어 Runtime Constant Pool에 값을 복사한다.
  • static 변수는 해당 영역에 저장되지만, 기본형이 아닌 static 클래스형 변수는 레퍼런스 변수만 저장되고 실제 인스턴스는 Heap에 저장되어 있다.

네이티브 메소드 스택

자바 이외의 언어로 만들어진 코드들을 위한 스택 영역

JNI (Java Native Interface)를 통해 호출되는 C / C++ 등의 코드를 수행하기 위한 스택

JVM 스택과 마찬가지로 스레드 단위의 자료구조로 이루어져 있다.

JVM 내부에 영향을 주지 않기 위해 따로 메모리 공간을 활용한다.


참고 사이트