JVM(3) - Runtime Data Area
런타임 데이터 영역이란?⌗
OS에서 JVM에 할당해준 메모리 영역을 Runtime Data Area,
런타임 데이터 영역이라 한다.
런타임 데이터 영역은 그림 같이
- 스택
- PC
- 힙
- 메소드
- 네이티브 메소드 스택
5가지 영역으로 나눌 수 있다.
스택⌗
쓰레드마다 런타임 스택이 생성되며
자바에서 메서드를 호출할 때 메서드의 프레임이 저장되는 영역
그리고 그 프레임 안에는 지역변수, 인자값, 리턴값 등이 저장된다.
메서드 호출 하나 하나마다 새 프레임이 생성되어 스택에 쌓이고
메서드 호출이 정상적으로 종료되거나 예외가 발생시 프레임은 스택에서 빠져나와 소멸된다.
쓰레드가 종료시 쓰레드가 가지고 있는 스택도 제거된다.
스택에도 직접적으로 저장되는 값이 있고 힙영역에 저장되며 레퍼런스만 저장하는 값이 있는데
기본 자료형, Primitive Type
의 경우 스택 영역에 저장되고
기본 자료형을 제외한 타입의 경우
힙 영역에 저장되고 스택 영역의 레퍼런스값을 통해 연결된다.
PC Resisters⌗
쓰레드가 생성될 때마다 생성되어, 각 쓰레드마다 존재함.
쓰레드가 생성될 때마다 그 쓰레드가 어떠한 명령을 실행하게 될지에 대한 부분을 기록하는 메모리 공간을 말한다.
JVM은 Stacks-Base
방식으로 작동한다.
JVM은 CPU에 직접 명령을 수행하지 않고 Stack
에서 Operand
를 뽑아내 이를 별도의 메모리 공간에 저장하는 방식을 취하는데, 이러한 메모리 공간을 PC Registers
라고 한다.
연산을 위해 필요한 피연산자를 임시로 저장하기 위한 용도로 사용한다.
힙⌗
모든 스레드 간에 공유되는 영역이며
런타임 중에 생성된 개체, 클래스의 메타 데이터, 배열 등이 포함됨.
JVM이 종료되면 소멸되어 OS에 반환된다.
실행시 특정 플래그를 사용하여 JVM의 힙 요구량을 제어할 수 있으며,
GC
, Garbage Collector
에 의해 이 공간이 관리되고 필요없어진 리소스를 정리하여 공간을 정리한다.
힙::힙의 구조⌗
위에 그림은 일반적으로 알려진 힙의 구조다.
크게 Young Generation
과 Old Generation
영역으로 나뉘며
Young Generation
은
Eden
Survivor
영역으로 나뉘게 된다.
힙::Eden⌗
객체가 최초로 Heap
영역에 할당되는 장소
이 영역이 가득 찰시에
- 새로 할당할 객체의 참조여부를 확인
Live Object
, 즉 사용중인 객체를Suvivor
영역으로 넘김- 참조가 사라진
Garbage Object
의 경우 그대로 둠 Eden
영역을 모두 청소
힙::Survivor⌗
Survivor0
과 Survivor1
로 구성되는 영역
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 object
는 Heap
영역으로 옮겨졌다.
메소드 영역⌗
메서드 영역에서는 런타임 상수풀과 메서드 데이터 내용, 생성자 및 메서드의 코드 내용을 저장.
즉, 코드 레벨에 클레스 수준의 정보를 저장한다.
여기에 클래스 변수가 저장되며
해당 클래스가 코드에서 맨 처음 사용될 때 메서드 영역에 로딩되며
추가로 이때 클래스의 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 Pool
의Entry
는 인덱스 번호를 통해 접근- 객체의 접근 등 모든 참조를 위한 핵심 요소
메소드 영역::Field Information⌗
- 필드 타입
- 필드의 접근 제어자
public
/private
/protected
/static
/final
/volatile
/transient
메소드 영역::Method Information⌗
Constructor
, 생성자를 포함한 모든 메소드- 메소드 이름
- 메소드 반환 타입
- 메소드 파라미터 수와 타입
- 메소드의 접근 제어자
- 메소드 구현 부분이 있을 경우
- 메소드의 바이트 코드
- 메소드의 스택 프레임의
Operand Stack
및Local variable section
의 크기 Exception Table
메소드 영역::Class Variable⌗
Class
변수는static
키워드로 선언된 변수를 의미- 모든 인스턴스에 공유 되며 인스턴스가 없어도 직접 접근이 가능하다.
- 변수는 인스턴스의 것이 아니라 클래스에 속하게 된다.
- 클래스를 사용 하기 이전에 이 변수들은 미리 메모리를 할당 받은 상태가 된다.
final class
변수는 상수로 치환 되어Runtime Constant Pool
에 값을 복사한다.static
변수는 해당 영역에 저장되지만, 기본형이 아닌static
클래스형 변수는 레퍼런스 변수만 저장되고 실제 인스턴스는Heap
에 저장되어 있다.
네이티브 메소드 스택⌗
자바 이외의 언어로 만들어진 코드들을 위한 스택 영역
JNI
(Java Native Interface)를 통해 호출되는 C
/ C++
등의 코드를 수행하기 위한 스택
JVM 스택과 마찬가지로 스레드 단위의 자료구조로 이루어져 있다.
JVM
내부에 영향을 주지 않기 위해 따로 메모리 공간을 활용한다.