본문 바로가기

JAVA

[JAVA] 자바의 메모리 구조(feat. 클래스 로딩과 인스턴스 생성)

🖥️ 자바의 메모리 구조

자바 프로그램이 실행될 때, JVM(Java Virtual Machine)은 운영체제로부터 할당받은 메모리 공간을 크게 **런타임 데이터 영역(Runtime Data Area)**이라는 여러 영역으로 나누어 사용한다. 주요 영역은 다음과 같다.

1. 메서드 영역 (Method Area)

  • 역할: 프로그램 실행에 필요한 클래스 및 인터페이스의 구조 정보, static 변수/메서드, 런타임 상수 풀 등 공통 데이터를 관리하는 영역이다.
  • 클래스 정보: 클래스 로더가 .class 파일을 읽어들여 JVM 메모리에 적재할 때, 클래스의 이름, 부모 클래스 이름, 인터페이스 정보, 필드 및 메서드 정보 등이 이곳에 저장된다.
  • static 영역: static으로 선언된 변수(클래스 변수)와 static 메서드는 인스턴스 생성과 무관하게 이 영역에 저장되어 모든 인스턴스가 공유하여 사용한다.
  • 런타임 상수 풀 (Runtime Constant Pool): 클래스 파일 내의 상수(리터럴 상수, 클래스/메서드 참조 정보 등)들이 JVM이 실제로 참조할 수 있는 형태로 저장되는 공간이다.

2. 힙 영역 (Heap Area)

  • 역할: 자바에서 new 키워드를 통해 생성되는 모든 객체(인스턴스)와 배열이 저장되는 공간이다.
  • 인스턴스의 멤버 변수: 객체가 생성될 때, 해당 객체의 멤버 변수(인스턴스 변수)들은 힙 영역에 각각 개별적으로 메모리가 할당되어 관리된다.
  • 인스턴스 메서드: 인스턴스 메서드의 코드는 힙 영역에 개별적으로 저장되지 않는다. 대신, 클래스 로딩 시 메서드 영역에 저장되고, 힙 영역의 각 인스턴스는 필요할 때 메서드 영역에 있는 해당 메서드를 참조하여 호출한다. 모든 인스턴스가 동일한 기능을 수행하는 메서드를 공유하기 때문에 메모리 효율성을 높이는 방식이라고 할 수 있다.

3. 스택 영역 (Stack Area)

  • 역할: 메서드 호출과 관련된 지역 변수, 매개변수, 리턴 값, 그리고 메서드 실행 시 필요한 임시 데이터가 저장되는 공간이다.
  • 메서드 호출: 메서드가 호출될 때마다 해당 메서드를 위한 **스택 프레임(Stack Frame)**이 스택 영역에 차곡차곡 쌓인다. 메서드 실행이 완료되면 해당 스택 프레임은 스택에서 제거된다.
  • 생명 주기: 스택 영역의 데이터는 메서드 호출이 끝나면 자동으로 소멸된다.

➡️ 클래스 로딩과 인스턴스 생성

  • 클래스 로딩 (Class Loading):
    • 주체: JVM의 클래스 로더(Class Loader)
    • 시기: JVM이 특정 클래스를 처음 사용할 때 (예: new 키워드로 인스턴스를 생성하거나, static 멤버에 접근할 때).
    • 과정: .class 파일을 읽어들여 클래스의 모든 메타 정보(클래스 이름, 멤버 변수 정보, 메서드 정보 등)를 메서드 영역에 적재하는 과정이며, 이때 static 변수들도 초기화된다.
    • 목적: 해당 클래스의 구조와 동작 방식에 대한 설계도를 JVM이 이해하고 사용할 수 있도록 메모리에 준비시키는 것이다.
  • 인스턴스 생성 (Instance Creation):
    • 주체: 개발자가 작성한 코드(new 키워드)
    • 시기: new 연산자를 사용하여 명시적으로 객체를 만들 때.
    • 과정: 클래스 로딩이 완료된 후, 해당 클래스의 설계도에 따라 **힙 영역에 실제 객체(인스턴스)**를 위한 메모리를 할당하고, 생성자를 호출하여 멤버 변수들을 초기화한다.
    • 목적: 실제 데이터를 저장하고 메서드를 호출할 수 있는 "살아있는" 객체를 만드는 것이다.