[기초 공부] JVM 정리

JVM(Java Virtual Machine)

자바 바이트 코드로 컴파일된 프로그램을 실행하는 가상 머신

  • 가상 머신: 컴퓨터 시스템을 가상화하는 프로그램 (OS에 의존하지 않도록 하기 위함)
  • JRockit: Oracle에 의해 개발되었으며, Java 6 이후 HotSpot으로 통합되어 개발 중지된 JVM
  • HotSpot: Oracle에 의해 개발되고 있는 JVM, 가장 많이 사용되며 충분히 검증되어 있음
  • OpenJ9: Eclipse에 의해 개발되고 있는 JVM, 메모리 사용률이 낮다는 벤치마킹 결과를 내세우고 있음

Class loader

자바 바이트 코드가 담긴 클래스들을 해석하고, 메모리에 적재하는 컴포넌트

  • 런타임 환경에서 클래스를 동적으로 로드함

Interpreter

자바 바이트 코드를 실행하는 컴포넌트

  • JIT(Just-in-time) 컴파일러: 실행 중에 바이트 코드를 컴파일하여 실행 속도를 향상시킴
    • 자주 실행되는 코드에 활용됨

Run-time Data Areas


JVM에서, 프로그램의 실행을 위한 영역

Per-thread Area

스레드마다 개별적으로 갖는 영역

  • PC 레지스터: 실행되고 있는 JVM 명령의 위치(returnAddress)를 기억하는 곳
  • JVM Stack: 지역 변수와 부분 결과 등의 값들을 Frame이라는 단위로 저장하는 곳
    • Frame: 각 메소드 실행에 대응하는 단위, 지역 변수 등 실행에 필요한 값들을 저장
    • 설정된 스택 크기를 초과하면 StackOverflowError 예외를 던짐
  • Native Method Stack: (주로 C로 작성된) native 메소드를 위한 스택 영역
    • 설정된 스택 크기를 초과하면 StackOverflowError 예외를 던짐

Heap

모든 스레드가 공유하며, 클래스 인스턴스와 배열을 저장하는 영역

  • Heap 내 object는 가비지 컬렉터에 의해 자동으로 제거됨 (GC)
  • 설정된 힙 크기를 초과하면 OutOfMemoryError 예외를 던짐

Method Area

모든 스레드가 공유하며, 메소드와 클래스 정보를 저장하는 영역

  • 각 클래스마다의 필드와 메소드 정보, 메소드와 생성자의 코드 등을 저장함
  • Run-time Constant Pool: 숫자나 메소드/필드 참조 등의 일부 상수들을 저장하는 공간
  • 설정된 메소드 영역 크기를 초과하면 OutOfMemoryError 예외를 던짐

HotSpot JVM

성능 병목(hot spot)을 감지하여 최적화하는 목적의 Oracle의 JVM

VM Configurations

사용 목적에 따라 최적화할 수 있도록, 여러 종류의 VM 중 택할 수 있는 기능

  • client VM: 프로그램 시작 시간을 줄이기 위해 튜닝된 VM (-client 인자로 적용)
  • server VM 프로그램 실행 시간을 줄이기 위해 튜닝된 VM (-server 인자로 적용)
  • 대부분의 상황에 server VM이 유리하므로, Java 9부터는 server VM만 제공하도록 변경됨

Tiered Compilation


컴파일 수준을 계층화하여, server VM의 빠른 실행과 client VM의 빠른 시작을 모두 얻는 기능

  • C1(client 컴파일러)으로 컴파일하다가, 코드가 자주 사용된다고 판단되면 C2(server 컴파일러)로 컴파일함
  • Java 7부터 제공되며, Java 8부터 기본으로 설정됨

Generational GC


Aging을 활용하여 Heap 내 object들을 최적화하는 GC

  • Young 영역: short-lived object들을 저장하는 곳
    • Eden 영역: 대부분의 object들이 저장되는 영역
    • Survivor 영역: minor GC를 위한 두 개의 영역, 항상 한 쪽은 비어 있음
  • Old 영역: Young 영역에서 오래 살아남은 object들을 저장하는 곳

Minor GC

Young 영역이 가득 찼을 때 발생하는 GC (매우 빠름)

  1. 비어 있는 한 쪽 Survivor 영역으로, Eden과 다른 Survivor 영역의 live object들을 이동시킴
  2. 오래 살아남은 object들을 Old 영역으로 이동시킴

Major GC

Old 영역이 가득 찼을 때 발생하는 GC (매우 느림)

Garbage Collectors

상황에 따라 효율적인 GC를 위해 선택할 수 있는 Collector

  • Serial Collector: 단일 스레드로 작동하여, 스레드 통신 오버헤드가 없는 Collector
  • Parallel Collector: 다중 스레드로 작동하여, 처리율이 비교적 높은 Collector
  • CMS: marksweep 단계를 통해 청소하는 동시적인 Collector
  • G1: 높은 처리율을 위해, 목표로 하는 stop-the-world 시간을 맞추려고 하는 동시적인 Collector
    • stop-the-world: GC를 위해 모든 스레드가 멈추는 시간
    • CMS을 대체하기 위해 탄생했으며, Java 9부터 기본 설정임
  • ZGC: 매우 큰 Heap에서의 낮은 지연 시간을 목표로 하는 동시적인 Collector
    • Java 11부터 지원하는 실험적인 기능

JVM Troubleshooting

JVM의 문제를 진단하기 위해 사용할 수 있는 도구들

jcmd Utility

$ jcmd <process id/main class> <command> [options]

JVM에 진단 명령을 요청하기 위한 JDK 내 CLI 유틸리티

  • Heap dump, Thread dump 등 다양한 진단 기능을 제공함
    • Heap dump: OutOfMemoryException 문제를 진단하기 위해 Heap 상태 확인
    • Thread dump: 스레드 데드락 문제를 진단하기 위해 모든 스레드의 상태 확인

좋은 웹페이지 즐겨찾기