본문 바로가기

개발/Basics

[Java/Basics] 자바 기초 스터디 1주차: 자바의 실행 구조와 메모리 모델(동작 원리)

먼저 왜 언어를 공부할 때 실행 구조와 메모리를 이해하면 좋은 지 알아보고, 실행 과정, JVM의 구성 요소, 메모리 구조와 에제 코드에 대해 작성한다.

1. 왜 언어 실행 구조와 메모리 모델을 이해해야 할까?

돌아간다 신난다를 위해서는 사실 이론에 대한 공부는 딱히 하지 않아도 된다.
하지만 구현을 넘어 더 딥한 고민으로 퀄리티 있는 코드를 짜기 위해서는 동작 원리를 이해해야 한다.

언어에 대한 깊은 이해를 하고 코드를 짜면 좋은 점

  • 효율적인 메모리 사용

    • 메모리 사용 최적화 가능
    • Garbage Collection의 작동 원리를 알면 메모리 누수 방지 가능(객체 참조 적시에 제거하는 등)
  • 디버깅과 문제 해결 능력 향상

    • NullPointerException, StackOverflowError, OutOfMemoryError와 같은 문제를 발생 원인부터 파악 가능
      • ex: Stack에 메서드 호출 정보가 저장됨을 이해하면, 재귀 호출이 과도해지면 에러가 발생할 수 있음을 예측 가능
  • 성능 최적화

    • JVM의 실행 구조를 이해하면 불필요한 오버헤드를 줄이고 최적화된 코드 작성 가능
      • ex: JIT(Just-In-Time) 컴파일러는 자주 실행되는 코드를 네이티브 코드로 변환하여 성능을 향상시키므로 성능에 민감한 부분에서는 반복적인 연산을 줄일 필요가 있음.
  • 멀티스레드 환경에서 안정적 코드 작성

    • JVM 메모리 모델을 이해하면 멀티스레드 환경에서 발생하는 문제(ex: 경쟁 조건, 데드락)를 피할 수 있음
      • ex: 메모리 동기화의 중요성을 이해하고, volatile 키워드나 synchronized 블록의 필요성 알 수 있음
  • 코드 설계 능력 향상

    • 객체 생성과 생명주기를 고려하여 설계 가능
      • 객체를 필요 이상으로 생성하지 않고 재사용(싱글톤 패턴 활용 등)
  • 의도하지 않은 메모리 공유 문제 방지

    • static 변수와 인스턴스 변수가 메모리에 저장되는 방식을 이해하면, 공유되는 데이터의 설계 명확히 가능
  • 프레임워크와 라이브러리 사용 이해도 증가

    • Spring, Hibernate와 같은 프레임워크는 내부적으로 JVM의 메모리 구조와 GC 동작을 활용.
      • ex: Spring의 Bean Scope(Singleton, Prototype)을 활용할 때 객체가 메모리에서 어떻게 관리되는지 알면 적절한 스코프 설정 가능
  • 안정성과 유지보수성 향상

    • 코드 작성 시 메모리 구조를 고려하면 잠재적 성능 병목을 줄이고, 유지보수 비용 감소.
      • ex: Immutable 객체를 활용하면 스레드 안전성을 높일 수 있음

    이런 사실을 인지하고 코드를 짜는 것과 모르고 남들이 다 이렇게 짜니까 짜는 것은 처음에는 크게 차이가 나지 않을 수 있어도 시간이 지날수록 많은 차이를 보일 것이다. 나는 지금이라도 그 격차를 줄여보고자 자바의 동작 원리에 대해 확실히 알고 넘어가고자 한다.

2. 자바의 실행 과정

2-1. 소스코드 작성(.java 파일)

  • 개발자가 작성한 자바 코드

    2-2. 컴파일(.class 파일)

  • javac 컴파일러를 통해 바이트코드로 변환
  • 운영체제나 하드웨어에 독립적인 형태로 변환됨

    2-3. 실행(JVM)

  • JVM이 바이트코드를 읽고, 인터프리터 및 JIT 컴파일러로 실행.
  • JVM은 자바 프로그램의 플랫폼 독립성 보장
    todo: (다이어그램 추가하기)

3. JVM 구성 요소

3-1. ClassLoader

  • 클래스 파일을 읽고 메모리에 로드.
  • 동적으로 필요한 클래스를 로드해주는 역할.

3-2. Execution Engine

  • 바이트코드를 해석하고 실행.
  • 인터프리터(순차 실행)와 JIT(자주 실행되는 코드 최적화)로 구성.

3-3. Runtime Data Area

  • 프로그램 실행 중 데이터를 저장하는 메모리 영역. (Heap, Stack 등)

3-4. Garbage Collector(GC)

  • 사용하지 않는 객체를 메모리에서 자동으로 제거.
    todo: (설명, 그림 추가하기)

4. JVM의 메모리 구조

4-1. Method Area

  • 클래스 정보, 상수, 메서드 코드 등 저장

    4-2. Heap

  • 객체가 저장되는 공간.(GC 관리)

    4-3. Stack

  • 메서드 호출과 지역 변수 저장

    4-4. PC Register

  • 현재 실행 중인 명령어의 주소 저장.

    4-5. Native Method Stack

  • 네이티브 코드(플랫폼 종속 코드) 실행 시 사용.
    todo: (그림, 설명 추가)

5. 예제 코드

public Class Main {
    public static void main(String[] args) {
        int x = 10;                    // Stack에 저장
        String str = "Hello";        // String Pool(Heap에 저장)
        Object obj = new Object();    // Heap에 저장
    }
}

6. 정리

  • 요약
    • 자바는 소스코드를 바이트 코드로 컴파일하고, JVM이 실행하는 구조.
    • JVM은 ClassLoader, Execution Engine, Garbage Collector, 메모리 구조로 구성되어 안정성과 효율성을 제공

todo: GC 작동원리 + JIT컴파일러와 인터프리터 차이 정리하기

다음주 금요일 시험이므로 일단 큰 맥락만 정리했다. 이후 정리 추가 예정!