J-S-06 JVM 기본 이론 및 메모리 관리 메커니즘

글 정보
카테고리
Programming/Java/Starter
태그
JavaLevel2

1. JVM의 본질과 시스템 내 위치

1.1. 컴퓨터 구조와 JVM (User Space vs Kernel Space)

가장 먼저 이해해야 할 것은 "JVM은 어디에 있는가?"입니다.

PC 시스템은 크게 물리적인 하드웨어(HW)와 논리적인 소프트웨어(SW)로 나뉩니다.

즉, JVM은 "OS 이론과 컴퓨터 구조론을 소프트웨어적으로 구현(짬뽕)해 놓은 가상 머신" 입니다.

실제 하드웨어가 없지만, 소프트웨어적으로 CPU, Register, Memory 등을 흉내 내어 만든 논리적 컴퓨터라고 볼 수 있습니다.

1.2. C++와 Java의 메모리 관리 철학 차이

두 언어는 메모리를 대하는 태도가 정반대입니다.


2. JVM의 핵심 아키텍처 (Architecture)

JVM은 크게 Class Loader, Runtime Data Area, Execution Engine의 세 부분으로 구성됩니다.

2.1. Class Loader (클래스 로더)

자바 컴파일러(javac)가 만든 .class 파일(바이트코드)을 런타임에 메모리로 가져오는 역할을 합니다.

2.2. Runtime Data Area (런타임 데이터 영역)

JVM이 OS로부터 할당받은 메모리 공간입니다.

2.3. Execution Engine (실행 엔진)

메모리에 로드된 바이트코드를 실제로 실행하는 장치입니다. 바이트코드는 기계어가 아니므로 CPU가 이해할 수 있도록 변환이 필요합니다.


3. 심화: 객체 생성과 실행의 세부 과정

3.1. 객체 생성의 내부 메커니즘 (Heap Allocation)

코드에서 new MyClass()를 호출하면 힙 영역에서는 다음과 같은 일이 벌어집니다.

  1. 메모리 공간 확보: 객체를 저장할 연속된 메모리를 할당합니다. (견적서 제외, 실제 내용물 크기만큼)
  2. 객체 헤더 설정: 객체 관리를 위한 필수 정보를 헤더에 기록합니다.
    • _Identity HashCode:_ 객체 고유의 해시값.
    • _GC Age:_ GC가 몇 번이나 지나갔는지 기록 (오래 살아남은 객체 구분을 위해).
    • _Lock 정보:_ 스레드 동기화를 위한 락 상태.
  3. 생성자(Constructor) 호출: 필드 값을 초기화합니다. (기본값보다 생성자에서 설정한 값이 우선시되는 이유)

3.2. Bytecode와 상수 풀 (Constant Pool)

.class 파일은 JVM이 읽을 수 있는 16진수 파일입니다.


4. 결론 및 주의사항

4.1. JNI (Java Native Interface)

기본적으로 JVM은 OS와 분리되어 있지만, JNI를 통해 Native Method Library(C/C++로 작성된 라이브러리)를 사용할 수 있습니다.

이를 통해 OS의 고유 기능을 직접 제어하거나 하드웨어 성능을 극한으로 끌어올릴 수 있습니다.

4.2. 마지막 강조: GC에 개입하지 말 것

메모 정리 과정에서 가장 중요한 원칙이 있습니다.

"코드에서 System.gc()를 명시적으로 호출하지 마세요."
public class GCAntiPattern {
    
    public void processData() {
        // 1. 객체 생성 및 사용
        String tempData = new String("잠시 사용하는 데이터");
        System.out.println(tempData);

        // 2. 사용 종료 (참조 해제)
        // 변수에 null을 대입하거나, 메서드가 종료되면 알아서 수거 대상이 됩니다.
        tempData = null; 

        // 🚫 [BAD] 명시적 GC 호출 금지
        // "지금 당장 청소해!"라고 강요하는 이 코드는 
        // 전체 애플리케이션을 순간적으로 멈추게(Stop-The-World) 할 수 있습니다.
        System.gc(); 
    }
}