본문 바로가기

Java

[Java] JVM 메모리 구조 탐구

자바 메모리와 컴퓨터 메모리

자바 메모리컴퓨터 메모리는 같은 물리적 메모리를 가리키지만, 이 두 개념은 다른 레벨에서 다루는 메모리 관리 방식이다.

자바 메모리는 컴퓨터 메모리를 관리하는 소프트웨어적 관점을 반영한 것이고, 컴퓨터 메모리는 하드웨어적인 관점에서 메모리 구조와 작동 방식을 설명한다.이제 자바 메모리컴퓨터 메모리의 관계와 차이점에 대해 알아보자.

 

1. 컴퓨터 메모리 (하드웨어 관점)

  • 컴퓨터 메모리는 물리적인 하드웨어 자원으로, 데이터와 명령을 저장하고 처리하기 위해 사용된다.
  • 컴퓨터 메모리는 크게 주기억 장치(RAM)보조기억 장치(HDD, SSD)로 나눌 수 있습니다.

 

RAM (Random Access Memory):

  • 주기억 장치로, 데이터를 일시적으로 저장하고, 컴퓨터가 실행 중인 프로그램이 사용합니다.
  • 휘발성 메모리이기 때문에 전원이 꺼지면 저장된 데이터가 모두 사라집니다.
  • CPU와 직접 연결되어 데이터의 처리 속도가 빠릅니다.

HDD, SSD (보조기억 장치):

  • 비휘발성 메모리로, 데이터를 장기적으로 저장합니다.
  • RAM보다 속도는 느리지만 대용량 데이터를 저장하는 데 적합합니다.
  • 프로그램과 파일이 저장되는 곳입니다. 실행 중인 프로그램은 일단 RAM에 올라가서 처리됩니다.

 

이러한 물리적 메모리는 모든 프로그램, 운영 체제, 데이터가 사용하는 공간이며, 자바 프로그램도 이 컴퓨터 메모리를 사용한다.

자바 프로그램이 실행되면 컴퓨터 메모리의 일부를 할당받아 사용하게 된다.


2. 자바 메모리 (소프트웨어 관점)

자바 메모리 구조는 자바 프로그램이 실행될 때 JVM(Java Virtual Machine)이 컴퓨터 메모리를 어떻게 관리하고 사용하는지에 대한 추상적 모델이다. 자바 메모리 구조는 물리적인 메모리 위에 JVM이 프로그램 실행을 위해 사용하는 메모리 모델이다.

그렇다면 메모리 영역을 알아보기 전 JVM에 대해서 알아보자.

 

JVM

자바 코드를 바이트코드(Bytecode)로 변환하여 실행하며, 자바 프로그램을 실행하고 메모리를 관리하는 중요한 역할을 수행

  • JVM은 Java Virtual Machine의 약자로, 자바 가상 머신이라고 불린다.
  • 자바와 운영체제 사이에서 중개자 역할을 수행하며, 자바가 운영체제에 구애 받지 않고 프로그램을 실행할 수 있도록 도와준다.
  • (JVM 설치만 하면 어떤 운영체제에서든 java 파일을 실행할 수 있다.)
  • 가비지 컬렉터를 사용한 메모리 관리도 자동으로 수행한다.
  • 다른 하드웨어와 다르게 레지스터 기반이 아닌 스택 기반으로 동작한다.

 

JVM의 구조

 

1) 클래스 로더(Class Loader)

  • 클래스 로더는 자바 바이트코드를 JVM에 로드하는 역할을 한다.
    • 즉, 자바 바이트코드를 메모리에 적재하여 JVM이 실행할 수 있도록 준비한다.
  • 클래스 파일(.class)은 디스크에 저장되어 있다가, 런타임 시점에 메모리로 로드된다.
  • 세 가지 클래스 로더:
    1. 부트스트랩 로더(Bootstrap ClassLoader): JVM의 최상위 로더로, 자바 표준 라이브러리(JDK 클래스)를 로드한다.
    2. 확장 로더(Extension ClassLoader): 확장 클래스 라이브러리를 로드한다.
    3. 애플리케이션 로더(Application ClassLoader): 사용자 애플리케이션의 클래스를 로드한다.

 

2) 메모리 구조

  • JVM은 메모리를 효율적으로 관리하기 위해 몇 가지 영역으로 나누어 사용한다.
  • 이는 자바 프로그램이 실행되면서 사용하는 데이터와 객체를 관리하는 중요한 구조이다.

1. 메소드(Method) 영역:

  • 클래스의 메타 정보(클래스명, 메서드, 필드 정보), 정적 변수, 상수 풀(Constant Pool) 등이 저장된다.
  • JVM이 실행될 때 메모리에 로드되며, 프로그램이 종료될 때까지 유지된다.

2. 힙(Heap) 영역:

  • 객체 인스턴스가 저장되는 공간이다.
  • 모든 객체는 힙 영역에 저장되며, 가비지 컬렉터(Garbage Collector)에 의해 메모리가 관리된다.

3. 스택(Stack) 영역:

  • 메서드 호출 시마다 생성되는 스택 프레임을 저장하는 공간이다.
  • 각 프레임에는 로컬 변수, 매개변수, 메서드 호출 정보가 포함된다.
  • 메서드가 호출될 때 프레임이 생성되고, 메서드가 종료되면 프레임이 제거된다.

4. PC 레지스터(Program Counter Register):

  • 현재 실행 중인 명령의 주소를 저장한다.
  • 자바 프로그램이 멀티 스레드로 실행될 때, 각 스레드는 자신만의 PC 레지스터를 가진다.

5. 네이티브 메소드 스택(Native Method Stack):

  • 자바가 아닌 네이티브 코드(C, C++ 등)로 작성된 메서드가 호출될 때 사용되는 스택이다.
  • 자바가 아닌 외부 라이브러리 또는 시스템 호출이 사용될 때 이 영역이 필요하다.

 

3) 실행 엔진(Execution Engine)

 

실행 엔진은 로드된 바이트코드를 실행하는 역할을 한다.

실행 엔진은 바이트코드를 운영체제와 하드웨어에서 이해할 수 있는 기계어(machine code)로 변환하고 실행한다.

  • 인터프리터(Interpreter):
    • 바이트코드를 한 줄씩 해석하고 실행한다.
    • 실행 속도가 느리다는 단점이 있지만, 즉시 실행이 가능하다.
  • JIT 컴파일러(Just-In-Time Compiler):
    • 성능을 높이기 위해 반복적으로 실행되는 코드는 인터프리터 방식이 아니라 JIT 컴파일러가 전체 메서드를 기계어로 변환해둔다.
    • 변환된 코드는 캐시되어, 다음 호출 시 빠르게 실행된다.
    • JIT 컴파일러 덕분에 자바 프로그램이 효율적으로 실행된다.
  • 가비지 컬렉터(Garbage Collector):
    • 힙 메모리에서 사용하지 않는 객체를 자동으로 정리하여 메모리를 회수한다.
    • 프로그래머가 직접 메모리를 해제할 필요 없이 JVM이 메모리 누수를 방지하고 효율적으로 메모리를 관리한다.

 

4) 네이티브 메서드 인터페이스(Native Method Interface, JNI)

  • 자바가 아닌 **네이티브 코드(C, C++ 등)**와의 상호작용을 가능하게 하는 인터페이스이다.
  • 이를 통해 자바 프로그램이 운영 체제나 하드웨어에 의존적인 코드를 실행할 수 있다.

5) 네이티브 메서드 라이브러리(Native Method Libraries)

  • JNI를 통해 호출할 수 있는 네이티브 코드 라이브러리가 저장되는 공간이다.

 

참고

  • JVM의 메모리 구조는 실제로는 컴퓨터의 RAM에서 공간을 차지힌다.
  • 즉, JVM의 메모리 영역이지만, RAM 위에서 동작하는 구조이다.