Runtime Data Area는 Java 애플리케이션이 실행될 때 JVM이 운영체제로부터 할당받은 메모리 영역을 의미한다.
Runtime Data Area의 구성 요소는 아래와 같다.
운영체제로부터 할당 받은 메모리 영역을 JVM이 효율적으로 사용하기 위해 설계된 결과라고도 할 수 있다.

스레드와 함께 표현하면 다음과 같다. 스레드끼리는 서로의 메모리를 참조할 수 없지만 Heap, Method Area는 모든 스레드가 공유한다.

각 영역을 간단하게 정리해보자.
Method Area에는 Class Loader가 로드한 클래스들에 대한 데이터를 저장한다.(번외-클래스의 로드는 언제 필요할까?)
이는 애플리케이션이 실행될 때 메모리에 올라가고, 종료될 때 해제된다.
Method Area 내부에는 Runtime Constant Pool이라는 이름이 붙은 영역이 존재한다. 이는 클래스에 하나씩 존재한다.
이 영역에는 런타임 시 필요한 참조 정보를 저장한다.
처음 클래스가 로드될 때는 클래스의 바이너리 코드에 포함된 Constant Pool에 메타 데이터(symbolic reference 등)가 저장되어 있다가
메서드나 클래스가 사용될 때 Class Loader의 링킹 단계를 거쳐서 symbolic reference가 실제 물리 레퍼런스로 변환되어 Runtime Constant Pool에 저장된다.

이 영역에 클래스 데이터가 존재하기에 인스턴스를 생성하기 위해선 이 영역을 참조해야 한다. 그래서 모든 스레드가 공유한다.
이를 반대로 말하면 시스템 전체적으로 공유되는 클래스는 Method Area에 등록하는 것이 효율적이다는 말이 된다.
대표적인 예로 Math와 같은 Util 클래스가 있다. 이러한 클래스는 모든 필드 변수와 메서드를 정적으로 선언해야 한다.
Stack은 임시 데이터가 저장되는 공간이다. PC Register, Native Method Area와 함께 스레드가 생성될 때마다 할당된다.
스택의 저장 단위는 Frame이다. Frame은 자바에서 중괄호 {}로 둘러싸인 영역을 의미한다.
Frame 내에서 사용되는 지역변수, 매개변수, 리턴값 등이 Stack에 저장된다.
아래 사진을 통해 더 자세히 알아보자.
만약 스레드가 사용 가능한 Stack의 사용 범위를 넘으면 StackOverflowError가 발생한다.
스택으 동적으로 확장할 때 또는 새로운 스레드를 만들 때 Stack에 할당할 메모리가 부족하다면 OutOfMemoryError가 발생한다.

Heap에는 런타임 중에 동적으로 생성된 인스턴스가 저장된다. Heap에는 실제 인스턴스 정보가 저장되며, Stack에는 인스턴스에 접근하기 위한 참조값이 저장된다.
만약 Heap 영역이 가득 차게 되면 OutOfMemoryError가 발생한다.
Heap은 GC(Garbage Collection)의 대상이 된다. JVM은 효율적인 GC를 위해 heap을 아래와 같은 구조로 나누었다.
GC에 대한 자세한 내용은 이 글에서 다룬다.

PC Register는 스레드가 현재 실행 중인 JVM 명령어를 가리킨다.
JVM은 Stack을 기반으로 동작하기 때문에 Stack에서 꺼낸 Operand를 PC Register에 저장한다(운영체제의 PC Register와 비슷한 역할을 가진 것 같다).
스레드가 생성되면 PC Register를 위한 공간도 함께 생성되고, 스레드가 소멸하면 같이 소멸한다.
만약 스레드가 Native 코드를 수행 중이라면 PC Register는 Undefined 값을 가지고 이에 대한 처리는 Native Method Stack에서 담당한다.
JVM에서 Native 언어(C/C++, 어셈블리)로 작성된 코드를 실행하기 위한 메모리 공간이다.
java 메서드가 아닌 Native 메서를 실행하면 이곳에 해당 메서드에 대한 정보가 저장된다.
impala 벨로그 - [JAVA] JVM - Runtime Data Area