Java

JDK 완벽 이해하기

Daesiker 2025. 10. 30. 10:43
반응형
반응형

개요

Java 개발을 시작하려면 가장 먼저 JDK를 설치해야 합니다. 하지만 단순히 "JDK를 설치하세요"라는 말만 듣고 넘어가기엔 아쉬운 부분이 많죠. 오늘은 JDK가 정확히 무엇인지, 내부 구조는 어떻게 되어 있는지, 그리고 어떤 버전을 선택해야 하는지까지 깊이 있게 다뤄보겠습니다.

 

JDK, JRE, JVM - 삼위일체의 관계

Java 생태계에서 가장 혼란스러운 부분이 바로 이 세 가지 개념입니다. 각각의 역할과 관계를 명확히 이해하는 것이 중요합니다.

JVM (Java Virtual Machine): Java 바이트코드(.class 파일)를 실행하는 가상 머신입니다. 플랫폼 종속적이며, 각 운영체제별로 다른 구현체가 존재합니다. JVM은 클래스 로더, 실행 엔진(인터프리터와 JIT 컴파일러), 가비지 컬렉터, 런타임 데이터 영역(힙, 스택, 메서드 영역 등)으로 구성됩니다.

JRE (Java Runtime Environment): JVM과 Java 표준 라이브러리(Java Class Library)를 포함합니다. Java 애플리케이션을 실행하는 데 필요한 최소한의 환경이죠. 과거에는 독립적으로 배포되었지만, Java 11부터는 JRE가 별도로 제공되지 않습니다.

JDK (Java Development Kit): JRE에 개발 도구들을 추가한 완전한 패키지입니다. javac(컴파일러), jar(아카이브 도구), javadoc(문서 생성), jdb(디버거) 등의 도구가 포함됩니다.

간단히 표현하면 JDK = JRE + 개발 도구, JRE = JVM + 표준 라이브러리입니다.

 

JDK의 내부 구조

JDK를 설치하면 다음과 같은 주요 디렉토리 구조를 확인할 수 있습니다.

bin 디렉토리: 실행 가능한 바이너리 파일들이 위치합니다. javac, java, jar, javap(역어셈블러), jconsole(모니터링 도구), jps(Java 프로세스 확인), jstack(스레드 덤프), jmap(힙 덤프) 등 개발과 디버깅에 필요한 다양한 도구들이 포함되어 있습니다.

lib 디렉토리: JDK가 사용하는 라이브러리 파일들이 저장됩니다. modules 파일에는 모듈화된 Java 플랫폼이 포함되어 있으며, Java 9 이후 도입된 JPMS(Java Platform Module System)의 핵심입니다.

include 디렉토리: JNI(Java Native Interface)를 사용한 네이티브 코드 개발에 필요한 C/C++ 헤더 파일들이 위치합니다.

conf 디렉토리: JVM 및 Java 플랫폼의 설정 파일들이 저장됩니다. logging.properties, security 디렉토리의 보안 정책 파일 등이 포함됩니다.

 

JDK 버전 선택 가이드

LTS (Long Term Support) vs Non-LTS: Oracle은 3년마다 LTS 버전을 출시합니다. 현재 LTS 버전은 Java 8, 11, 17, 21입니다. 프로덕션 환경에서는 LTS 버전을 사용하는 것이 안정성과 장기 지원 측면에서 유리합니다. Non-LTS 버전은 6개월마다 출시되며 최신 기능을 빠르게 사용할 수 있지만, 지원 기간이 짧아 프로덕션보다는 실험적 프로젝트에 적합합니다.

주요 LTS 버전별 특징: Java 8은 람다 표현식과 스트림 API를 도입했으며, 여전히 많은 레거시 시스템에서 사용 중입니다. Java 11은 var 키워드, HTTP 클라이언트 API, 문자열 메서드 확장 등이 추가되었고, Oracle JDK가 유료화되면서 OpenJDK의 중요성이 부각되었습니다. Java 17은 sealed 클래스, 패턴 매칭, 텍스트 블록 등 현대적인 언어 기능이 대거 추가되었습니다. Java 21은 가상 스레드(Project Loom), 레코드 패턴, switch 패턴 매칭 등 혁신적인 기능들이 정식 도입되었습니다.

새 프로젝트라면: Java 21 LTS를 권장합니다. 가상 스레드와 같은 최신 기능은 동시성 프로그래밍의 패러다임을 바꿀 만큼 강력합니다.

레거시 프로젝트라면: 현재 사용 중인 버전을 유지하되, 가능하다면 최소 Java 11 이상으로 마이그레이션을 계획하세요.

 

Oracle JDK vs OpenJDK

Oracle JDK: Oracle이 제공하는 공식 구현체입니다. Java 11부터 상용 환경에서 사용 시 구독 라이선스가 필요합니다. Oracle은 추가적인 성능 최적화, 고급 모니터링 도구, 그리고 상용 지원을 제공합니다.

OpenJDK: GPL 라이선스 하의 오픈소스 구현체입니다. Java 11 이후 Oracle JDK와 기술적으로 거의 동일하며, 무료로 사용 가능합니다. 다양한 벤더가 OpenJDK 기반의 배포판을 제공합니다.

 

JDK 설치 및 환경 변수 설정

설치 자체는 간단하지만, 환경 변수 설정을 제대로 이해하는 것이 중요합니다.

JAVA_HOME: JDK 설치 디렉토리를 가리키는 환경 변수입니다. 많은 빌드 도구(Maven, Gradle)와 IDE가 이 변수를 참조하여 JDK를 찾습니다. 예를 들어 /usr/lib/jvm/java-21-openjdk 또는 C:\Program Files\Java\jdk-21처럼 설정합니다.

PATH: JAVA_HOME/bin을 PATH에 추가하면 터미널 어디서든 java, javac 등의 명령어를 실행할 수 있습니다. Windows에서는 %JAVA_HOME%\bin, Unix/Linux에서는 $JAVA_HOME/bin을 추가합니다.

여러 버전 관리: 여러 JDK 버전을 사용해야 한다면 SDKMAN(Linux/Mac) 또는 jEnv 같은 버전 관리 도구를 활용하면 편리합니다. 프로젝트별로 다른 Java 버전을 쉽게 전환할 수 있습니다.

 

주요 JDK 도구 활용

javac: 소스 코드를 바이트코드로 컴파일합니다. -source와 -target 옵션으로 호환성을 제어할 수 있고, --release 옵션으로 더 간편하게 특정 Java 버전을 타겟팅할 수 있습니다.

javap: 클래스 파일을 역어셈블하여 바이트코드를 확인할 수 있습니다. -c 옵션으로 디스어셈블된 코드를, -v 옵션으로 상세 정보를 볼 수 있어 컴파일러가 생성한 코드를 분석하는 데 유용합니다.

jconsole / jvisualvm: JVM 모니터링 도구로, 메모리 사용량, 스레드 상태, CPU 사용률 등을 실시간으로 확인할 수 있습니다. 프로덕션 환경에서의 성능 문제 진단에 필수적입니다.

jps: 실행 중인 Java 프로세스 목록을 확인합니다. -l 옵션으로 전체 패키지명을, -v 옵션으로 JVM 인자를 확인할 수 있습니다.

jstack: 스레드 덤프를 생성하여 데드락이나 스레드 블로킹 문제를 분석할 수 있습니다.

jmap: 힙 덤프를 생성하거나 힙 메모리 통계를 확인할 수 있습니다. 메모리 누수 분석에 핵심적인 도구입니다.

 

성능 튜닝을 위한 JVM 옵션

JDK를 효과적으로 사용하려면 주요 JVM 옵션을 알아야 합니다.

메모리 관련: -Xms는 초기 힙 크기를, -Xmx는 최대 힙 크기를 지정합니다. 프로덕션 환경에서는 두 값을 동일하게 설정하여 힙 리사이징 오버헤드를 제거하는 것이 일반적입니다. -XX:MaxMetaspaceSize는 메타스페이스(클래스 메타데이터 저장 영역) 크기를 제한합니다.

가비지 컬렉터 선택: -XX:+UseG1GC(기본값, Java 9+), -XX:+UseZGC(저지연 GC), -XX:+UseShenandoahGC(Red Hat의 저지연 GC) 등 애플리케이션 특성에 맞는 GC를 선택할 수 있습니다.

디버깅 및 진단: -XX:+HeapDumpOnOutOfMemoryError로 OOM 발생 시 자동으로 힙 덤프를 생성하고, -XX:HeapDumpPath로 저장 위치를 지정할 수 있습니다.

 


참고 자료

 

반응형