# JVM과 컴파일 과정

# JVM이란?

  • JVM(Java Virtual Machine)
  • Java로 개발한 프로그램을 컴파일하여 만들어지는 바이트코드를 실행하기 위한 가상머신
  • 플랫폼 독립적으로 JVM이 실행 가능한 환경이라면 어디서든 실행 가능(OS에 독립적인 특성)

# 자바 컴파일 과정

  1. 개발자가 자바 소스코드(.java)를 작성
  2. 자바 컴파일러(Java Compiler)가 자바 소스파일을 컴파일
    • 자바 바이트 코드(.class)가 생성. 컴퓨터가 읽을 수 없고 자바 가상 머신이 이해 가능
  3. 컴파일된 바이트 코드를 JVM의 클래스 로더(Class Loader)에게 전달
  4. 클래스 로더는 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(JVM 메모리)에 로드
      1. 클래스 파일을 JVM 메모리에 로드
      1. 자바 언어 명세 및 JVM 명세에 명시된 대로 구성되어 있는지 검사
      1. 클래스가 필요로 하는 메모리 할당
      1. 클래스 상수 풀 내 모든 심볼릭 레퍼런스(클래스 등)를 다이렉트 레퍼런스(저장된 실제 주소)로 변경
      1. 클래스 변수들을 적절한 값으로 초기화 (static)
  5. 실행 엔진이 JVM 메모리에 올라온 바이트 코드들을 하나씩 실행. 실행 방법에는 인터프리터 방식과 JIT 컴파일러 방식 존재
    • 인터프리터 : 바이트 코드 명령어를 하나씩 읽어 해석하고 실행. 하나하나의 실행은 빠르지만 전체적인 실행 속도가 느림
    • JIT 컴파일러 : Just-In-Time Compiler. 바이트 코드 전체를 컴파일하고 이후에 해당 메서드를 바이너리 코드로 직접 실행하는 방식. 전체적인 실행 속도가 빠름

# 런타임 데이터 영역

  1. Static 영역(Method 영역)
  2. Heap 영역
  3. Stack 영역
  4. PC Register
  5. Native Method Stack

# Static 영역

  • Static으로 선언된 것들 저장
  • 컴파일 시간 동안 할당된 메모리, 런타임 중에는 값 변경 불가
  • 무분별하게 사용될 경우 메모리 부족 현상이 발생할 수 있음
  • JVM이 동작해서 클래스가 로딩될 때 생성되며, 프로그램이 종료될 때까지 메모리에 남아있음

# Stack 영역

  • 기본 자료형, 지역변수, 매개변수가 저장되는 메모리 영역
  • 객체 생성 시 참조 주소값도 저장
  • 스레드 별로 1개식 생성됨

# Heap 영역

  • 참조형의 데이터 객체의 실제 데이터들이 담기는 공간
  • new 키워드로 생성된 객체와 배열 등이 저장됨
  • 어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하지 않는다면 GC가 해당 인스턴스를 정리
  • 스레드 개수와 상관 없이 1개의 영역만 존재
Instance i = new Instance("객체")
  • 변수 i는 Stack 영역에, "객체"에 해당하는 데이터는 Heap 영역에 저장