[JVM 완전정복 #3] Runtime Data Area 완전분석: 메모리 구조와 각 영역 역할

2025. 11. 17. 21:34·자바

0. 들어가며

지난 글에서는 JVM의 클래스 로더(Class Loader)에 대해 알아보았습니다.
이번 글에서는 JVM 내부에서 프로그램이 실제로 실행될 때 데이터를 어떻게 저장하고 관리하는지 즉 Runtime Data Area(런타임 데이터 영역)에 대해 자세히 살펴보겠습니다.

Runtime Data Area는 JVM에서 자바 프로그램이 실행되는 동안 모든 데이터가 저장되고 CPU가 접근하는 핵심 메모리 공간입니다.
이 영역을 이해하면 메모리 구조 성능 최적화 스레드 안전 문제 등을 더 깊이 이해할 수 있습니다.

이번 글에서는 Runtime Data Area의 구성 요소와 각 역할 그리고 메모리 사용과 관련된 주의점까지 상세히 다루겠습니다.


1. Runtime Data Area란?

Runtime Data Area는 JVM이 자바 프로그램 실행 시 데이터를 저장하고 처리하는 메모리 공간입니다.
JVM 내부에서는 이 공간을 여러 영역으로 나누어 관리하며 각 영역마다 저장되는 데이터와 접근 방식이 다릅니다.
아래에서  자세히 다루겠습니다.

쉽게 말해 Runtime Data Area는 자바 프로그램 실행 중 필요한 모든 데이터의 저장소이자 작업 공간이라고 할 수 있습니다.


1-1. Runtime Data Area 구성 요소

JVM의 Runtime Data Area는 크게 다음과 같은 구성 요소로 나뉩니다. 아래그림을보면서 알아봅시다.   

이미지 출처 : https://www.tutorialspoint.com/how-many-types-of-memory-areas-are-allocated-by-jvm-in-java
 
메소드(Method) 영역 클래스 구조, 메서드 바이트코드, 런타임 상수풀(Constant Pool) 클래스 로딩 시 생성, 모든 스레드 공유
힙(Heap) 객체 인스턴스, 배열 JVM 전체에서 공유, 가비지 컬렉션 대상
스택(Stack) 메서드 호출 시 로컬 변수, 연산 결과, 복귀 주소 스레드별 독립적, 메서드 호출 시 증가/감소
프로그램 카운터(Program Counter, PC) 레지스터 현재 스레드가 실행 중인 명령어 주소 스레드별 독립적, 명령 흐름 관리
네이티브 메서드 스택(Native Method Stack) 네이티브 코드(C/C++) 실행 시 사용 스레드별 독립적, JNI 호출용

각 영역마다 메모리 접근 방식과 관리 주체가 다르므로, 프로그램 설계와 운영 관점에서 주의가 필요합니다.


1-2 메소드 영역(Method Area)

메소드 영역은 클래스 정보와 메서드 코드 런타임 상수 풀(Constant Pool) 등이 저장되는 공간입니다.

  • 클래스 로딩 시 클래스 구조, 메서드 바이트코드, 문자열 상수 등이 모두 올라갑니다.
  • 자바 8 이전에는 Permanent Generation(PermGen) 영역이었으나, 자바 8 이후에는 Metaspace로 변경되어 크기를 동적으로 관리합니다.
  • JVM은 메소드 영역에 로딩된 상수 풀을 바탕으로 심볼(Symbol) 참조를 실제 메서드 주소에 바인딩합니다.
  • 클래스가 많아질수록 메소드 영역과 상수 풀의 사용량이 급증할 수 있으며 이는 JVM 성능과 가비지 컬렉션에도 영향을 줍니다.

예를 들어 간단한 HelloWorld 클래스 하나를 로딩해도 클래스 메타데이터, 상수풀, 문자열 리터럴 등 상당량의 데이터가 메소드 영역에 올라갑니다.
즉 프로그램에서 사용하는 클래스 수가 많아질수록 메소드 영역의 메모리 사용량도 급격히 증가할 수 있다는 점을 기억해야 합니다.


1-3.  힙(Heap)

Heap 영역은 GC가 관리하는 메모리 영역으로 자바에서 사용되는  모든 객체 인스턴스와 배열이 저장되는 공간으로자바 프로그램에서 가장 중요한 메모리 영역 중 하나입니다.

힙은 스레드 간
공유 영역이므로 여러 스레드가 동시에 객체에 접근할 수 있습니다. 자바에서 객체를 생성할 때 new 를 사용하면 이 객체는 자동으로 힙 영역에 저장됩니다. 배열도 내부적으로 클래스이기 때문에 힙 영역에 위치하게 됩니다.

힙 영역의 특징과 중요 포인트를 단계별로 정리하면 다음과 같습니다.


1) 힙의 정의와 가비지 컬렉터(GC)

힙은 가비지 컬렉터가 관리하는 메모리 영역이라는 정의로 시작됩니다. 즉, 힙에 올라간 객체는 참조되지 않으면 GC가 자동으로 회수합니다.

  • 객체가 힙에 저장되는 과정:
    1. MyClass obj = new MyClass(); 처럼 new 연산자를 사용해 객체 생성
    2. JVM은 힙에서 필요한 메모리 공간을 할당하고 객체를 저장
    3. 참조자를 통해 객체에 접근 가능 (obj가 참조자 역할)
  • 객체 회수 과정:
    1. 참조자가 더 이상 존재하지 않거나 접근할 방법이 없을 때
    2. GC가 객체를 “참조되지 않은 개체”로 판단
    3. 메모리를 회수

여기서 중요한 점은 스코프(scope)와 참조자(live reference) 입니다.
예를 들어 지역 변수 t가 특정 메서드 안에서 선언되었다고 합시다. 메서드가 종료되어 스택 프레임이 사라지면  t라는 참조자도 사라집니다. 참조자가 사라진 순간 해당 객체는 GC의 회수 대상이 됩니다.

그러나 정적(static) 변수처럼 프로그램 전체에서 지속적으로 참조되는 경우, 객체는 프로그램 종료 시까지 힙에 남게 됩니다.
즉, GC가 절대 회수하지 않습니다. 이런 경우에는 메모리를 불필요하게 점유할 위험이 있으므로 주의가 필요합니다.


2) 힙의 구조: 세대별(Generation) 관리

힙은 단순히 하나의 공간이 아니라 세대별로 나누어 관리됩니다. 이를 세대별 컬렉션(Generational GC) 이론이라고 부릅니다.

  • 영 제너레이션(Young Generation)
    • 새로 생성된 객체가 위치하는 공간
    • 다시 Eden 영역과 Survivor 영역으로 세분화
    • 대부분의 객체가 이곳에서 생성되고 곧바로 회수됨
    • 짧은 수명을 가진 객체들이 대부분이므로 GC가 매우 빠르게 수행됨 (마이너 GC)
  • 올드 제너레이션(Old Generation)
    • Young Generation에서 살아남은 객체가 이동하는 공간
    • 오래 살아남은 객체들을 관리
    • GC가 오래 걸릴 수 있으며, 이를 메이저 GC라고 함
  • 메타스페이스(Metaspace)
    • 자바 8 이후 PermGen 영역이 대체된 영역
    • 클래스 메타데이터를 저장
    • GC가 필요할 수 있으나, 프로그램 로딩 후 대부분 장기간 유지

세대별 컬렉션을 통해 짧게 살아 사라지는 객체는 빠르게, 오래 살아남는 객체는 별도로 관리할 수 있어, GC 효율을 높일 수 있습니다.


3) 가비지 컬렉터 동작 이해

힙 관리의 핵심은 GC가 언제, 어떻게 객체를 회수하는가입니다.

  1. 참조 여부 판단
    • 스택 영역에서 객체에 대한 참조자가 존재하는지 확인
    • 참조자가 없으면 객체는 회수 대상으로 마킹
  2. 객체 이동 및 회수
    • Young Generation에서 살아남은 객체는 Old Generation으로 이동
    • 이동 과정에서 나이(age) 값 증가 → 일정 나이가 되면 Old Generation으로 승격
    • 참조자가 여전히 존재하면 객체는 유지
  3. Stop-The-World(STW)
    • GC가 힙을 청소하는 동안 JVM은 일시 정지
    • 모든 스레드가 멈추므로, 서버 환경에서는 길어지면 반응성이 떨어지고 장애 발생 가능
    • Minor GC는 Young Generation에서만 수행되므로 짧게 끝나지만, Major/Full GC는 Old Generation과 메타스페이스까지 청소하므로 시간이 길어질 수 있음

다음 글에서 GC에 대해 상세히 다루겠습니다.

 객체를 자주 생성하고 삭제하는 애플리케이션에서는 적절한 힙 크기와 GC 전략을 설정해야 성능 문제를 예방할 수 있습니다.

1-4. 스택(Stack)

스택 영역은 JVM에서 각 스레드(Thread)마다 독립적으로 존재하는 메모리 영역으로, 메서드 호출과 지역 변수 관리를 담당합니다. 힙과 달리 스택은 스레드 전용 영역이기 때문에 다른 스레드와 공유되지 않습니다.

스택은 LIFO(Last In, First Out) 구조로 동작하며 JVM에서 메서드가 호출될 때마다 새로운 스택 프레임(Stack Frame)이 생성되고 메서드가 종료되면 프레임이 사라지면서 자동으로 메모리가 해제됩니다.


1) 스택의 구조

스택은 기본적으로 메서드 호출 단위로 관리됩니다.
각 스택 프레임에는 다음과 같은 정보가 포함됩니다:

  1. 로컬 변수(Local Variables)
    • 메서드 내부에서 선언된 모든 지역 변수 저장
    • 변수 타입에 따라 메모리 슬롯 사용
      • 예: int, float → 1 슬롯, long, double → 2 슬롯
    • 참조 변수(객체 주소)는 힙 영역에 있는 실제 객체를 가리킵니다
  2. 연산 스택(Operand Stack)
    • 메서드 내부 연산 수행용 임시 공간
    • JVM 바이트코드 실행 시 피연산자를 스택에 push/pop하며 계산
  3. 프레임 데이터(Frame Data)
    • 메서드 반환 주소, 동적 링크(Calling Method 정보), 예외 처리 관련 데이터

2) 스택과 객체 참조

스택에는 객체 참조자만 저장되고 실제 객체 데이터는 힙에 위치합니다.
예를 들어:

 

 

void foo() {
   MyClass obj = new MyClass();
 }
  • obj 참조자는 스택의 로컬 변수 영역에 저장됩니다.
  • new MyClass()로 생성된 객체는 힙에 저장됩니다.
  • foo() 메서드가 종료되면 스택 프레임이 제거되면서 obj 참조자는 사라집니다.
  • 이때 힙의 객체가 더 이상 참조되지 않으면, GC가 회수 대상이 됩니다.

즉, 스택은 객체 자체가 아니라 참조자의 수명과 접근성을 관리하는 역할을 합니다.


    •  

4) 스택과 GC의 관계

스택은 GC가 객체의 참조 여부를 판단하는 기준이 됩니다.

  • 스택에 존재하는 참조자는 힙 객체가 살아있음을 의미
  • 참조자가 스택에서 사라지면, GC는 객체가 더 이상 접근 불가능하다고 판단
  • 따라서 스택 프레임의 수명과 구조는 객체 회수 시점에 직접적인 영향을 줌

예시:

 
void bar() { MyClass obj1 = new MyClass(); // obj1 -> 힙 객체 참조 { MyClass obj2 = obj1; // obj2 -> 같은 객체 참조 } // obj2 스코프 종료, obj1 참조 남음 } // obj1 스코프 종료 → 객체 더 이상 참조되지 않음 → GC 회수 가능

 


1-5. 프로그램 카운터(PC) 레지스터

프로그램 카운터는 현재 실행 중인 명령어 주소를 저장하는 영역입니다.

  • 스레드별로 독립적이며 JVM의 명령어 흐름을 관리합니다.
  • 바이트코드 수준에서 “지금 어떤 명령을 수행 중인지”, “다음에 무엇을 수행할 것인지” 정보를 제공합니다.
  • JVM 내부적으로 스택과 함께 메서드 호출 흐름을 관리하는 핵심 역할을 합니다.

1-6. 네이티브 메서드 스택(Native Method Stack)

네이티브 메서드 스택은 자바가 아닌 네이티브 코드(C/C++) 호출을 위해 사용되는 스택 영역입니다.

  • 각 스레드마다 독립적으로 존재합니다.
  • JNI(Java Native Interface)를 통해 호출되는 메서드의 로컬 변수와 상태 정보를 저장합니다.
  • 스택 오버플로가 발생할 수 있으므로 주의가 필요합니다.

2. Runtime Data Area 활용과 주의점

Runtime Data Area를 이해하면 JVM 메모리 관리와 성능 최적화가 한층 수월해 집니다..

  1. 메소드 영역은 클래스 로딩 시 증가하며 클래스 수가 많아질수록 메모리 사용량이 급증합니다.
  2. 힙은 객체를 저장하고 가비지 컬렉션이 관리합니다. 너무 크면 GC 부담이, 너무 작으면 메모리 부족 오류가 발생합니다.
  3. 스택은 스레드별 독립 영역이므로 재귀 호출 시 스택 소진 주의가 필요합니다.
  4. PC 레지스터와 네이티브 스택은 스레드 단위로 관리되므로 동시성 환경에서 스레드 안전성을 제공합니다.

즉, JVM 메모리 구조를 이해하고, 애플리케이션 특성에 맞게 힙/메소드 영역 크기, GC 전략, 스레드 관리를 조절하는 것이 중요합니다.


2. Heap 이 가득 차면 어떻게 될까?

힙이 가득 차면 JVM은 먼저 가비지 컬렉션을 수행하여 사용하지 않는 객체를 정리합니다.

  • GC 후에도 공간이 부족하면 JVM은 OutOfMemoryError를 발생시킵니다.
  • 이 문제를 예방하기 위해서는 JVM 옵션(-Xms, -Xmx)을 통해 힙의 초기 크기와 최대 크기를 적절히 설정해야 합니다.

마치며

이번 글에서는 JVM Runtime Data Area가 어떻게 구성되어 있고, 실제 실행 중에 어떤 방식으로 동작하는지 깊이 있게 살펴보았습니다. 정리하면서 자바 코드의 변수, 객체, 메서드들이 각각 어떤 메모리 영역에 배치되고 어떤 흐름으로 관리되는지 머릿속에 보다 선명한 구조로 그려지더군요.

추상적으로만 알고 있던 JVM 내부의 원리가 실제 동작 방식과 연결되면서 이해의 폭이 한층 넓어진 느낌이었습니다. 개인적으로도 매우 흥미로운 과정이었고, 이렇게 정리해보니 스스로도 조금 더 성장한 것 같아 뿌듯합니다.
다음엔  Garbage Collector에 대해서 다루어 보겠습니다.

 

그럼, 다음 글에서 또 만나요!

저작자표시 비영리 (새창열림)

'자바' 카테고리의 다른 글

[JVM 완전정복 #5] Execution Engine 완전정복: 인터프리터와 JIT의 비밀  (0) 2025.11.17
[JVM 완전정복 #4] Garbage Collector 이해하기  (0) 2025.11.17
[JVM 완전정복 #2] 자바 프로그램의 첫 관문 - 클래스로더  (0) 2025.11.17
JIT 컴파일러와 일반 컴파일러의 차이를 알아보자  (0) 2025.11.14
Java Class 하위에 변수를 몇개까지 선언할 수 있을까?  (0) 2025.11.11
'자바' 카테고리의 다른 글
  • [JVM 완전정복 #5] Execution Engine 완전정복: 인터프리터와 JIT의 비밀
  • [JVM 완전정복 #4] Garbage Collector 이해하기
  • [JVM 완전정복 #2] 자바 프로그램의 첫 관문 - 클래스로더
  • JIT 컴파일러와 일반 컴파일러의 차이를 알아보자
깊은바다속꼬북이
깊은바다속꼬북이
  • 깊은바다속꼬북이
    CodeBlossom
    깊은바다속꼬북이
  • 전체
    오늘
    어제
    • 분류 전체보기 (53) N
      • 라이징 캠프 (4)
      • 객채지향 개발론 (3)
      • 스프링 (10) N
      • 네트워크 (2)
      • 자바 (16)
      • 자료구조 (3)
      • 운영체제 (0)
      • 데이터베이스 (4)
      • 디자인패턴 (7)
      • JSP (1)
      • 개발 알쓸신잡 (2)
      • 일반 교양 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바 Socket 클래스
    JVM
    java
    JUnnit5
    개발 철학
    스프링
    junnit5프레임워크
    트랜잭션 전파레벨
    싱글턴 패턴(Singleton Pattern)
    한국어 검색
    자료구조
    mockito라이브러리
    spring
    개발 교훈
    어댑터 패턴(Adapter Pattern)
    MySQL 파서
    java data area
    템플릿 메서드 패턴(Template Method Pattern)
    개발자 철학
    디자인패턴
    객체지향
    전략 패턴(Strategy Pattern)
    java 버전별 특징
    GC
    프로그램밍 언어
    jvm 클래스 로더
    MySQL 옵티마이저
    백엔드
    jit-compiler
    디자인 패턴
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
깊은바다속꼬북이
[JVM 완전정복 #3] Runtime Data Area 완전분석: 메모리 구조와 각 영역 역할
상단으로

티스토리툴바