| 구분 | JDK | JRE | JVM | JAR | JIT |
|---|---|---|---|---|---|
| 정식 명칭 | Java Development Kit | Java Runtime Environment | Java Virtual Machine | Java Archive | Just-In-Time Compiler |
| 한줄 정의 | Java 개발 도구 모음 | Java 실행 환경 | Java 가상 머신 | Java 압축 파일 | 실시간 컴파일러 |
| 주요 목적 | Java 애플리케이션 개발 | Java 애플리케이션 실행 | 플랫폼 독립적 실행 | 배포 및 패키징 | 성능 최적화 |
| 사용 대상 | 개발자 | 일반 사용자 | 시스템 (내부) | 개발자/사용자 | 시스템 (내부) |
| 설치 필요성 | ✅ 개발 시 필수 | ✅ 실행 시 필수 | ⚙️ JRE에 포함 | ❌ 도구로 생성 | ⚙️ JVM에 포함 |
| 포함 관계 | JRE + 개발도구 | JVM + 라이브러리 | 독립적 | 독립적 파일 | JVM 내부 기능 |
┌─────────────────────────────────────┐
│ JDK │ ← 개발 도구 전체
│ ┌───────────────────────────────┐ │
│ │ JRE │ │ ← 실행 환경
│ │ ┌─────────────────────────┐ │ │
│ │ │ JVM │ │ │ ← 가상 머신
│ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ JIT │ │ │ │ ← 최적화 컴파일러
│ │ │ └─────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
┌─────────────┐
│ JAR │ ← 독립적인 패키징 파일
└─────────────┘
| 목적 | 추천 | 이유 |
|---|---|---|
| Java 학습 시작 | JDK 설치 | 컴파일부터 실행까지 모든 기능 |
| 서버 배포 환경 | JRE 설치 | 실행만 하면 되므로 경량화 |
| 애플리케이션 배포 | JAR 파일 생성 | 의존성 포함한 단일 파일 |
| 성능 최적화 | JIT 옵션 튜닝 | -XX:CompileThreshold 등 조정 |
| 메모리 튜닝 | JVM 옵션 설정 | -Xmx, -Xms 등 조정 |
JVM은 Java 코드를 어떤 운영체제에서든 실행할 수 있게 해주는 가상 머신임.
Java의 가장 큰 장점 중 하나가 "Write Once, Run Anywhere" 임.
// 이 코드를 한 번만 작성하면
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Windows에서 작성했어도 Linux, macOS에서 동일하게 실행됨.
JVM = 통역사
Java 소스코드 (.java)
↓ javac
바이트코드 (.class)
↓ JVM
기계어 실행
자주 사용되는 코드를 미리 기계어로 번역해서 프로그램을 빠르게 만들어주는 최적화 기술임.
초기 Java는 "느리다"는 인식이 있었는데, JIT 컴파일러 덕분에 이제는 C/C++에 버금가는 성능을 보여줌.
JIT = 똑똑한 비서
일반적인 상황:
- 매번 서류를 찾아서 → 복사하고 → 정리하는 반복 작업
JIT가 있는 상황:
- 자주 쓰는 서류는 미리 준비해두고 → 바로바로 제공
// 이런 반복문이 있다면
for (int i = 0; i < 1000000; i++) {
calculate(i); // 이 메소드가 계속 호출됨
}
calculate() 메소드가 자주 호출됨을 감지public class JITExample {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
// 같은 계산을 100만 번 반복
for (int i = 0; i < 1000000; i++) {
heavyCalculation();
}
long endTime = System.currentTimeMillis();
System.out.println("실행 시간: " + (endTime - startTime) + "ms");
// 처음에는 느리지만 점점 빨라짐!
}
private static void heavyCalculation() {
// 복잡한 계산 로직
Math.sqrt(Math.random() * 1000);
}
}
여러 개의 Java 클래스 파일과 리소스들을 하나로 묶어서 배포하기 쉽게 만든 압축 파일임.
JAR = 택배 상자
개별 배송 (번거로움):
- 컵 1개, 접시 1개, 수저 1세트를 각각 포장해서 배송
JAR 배송 (편리함):
- 모든 식기를 하나의 상자에 담아서 한 번에 배송
myapp.jar
├── com/
│ └── mycompany/
│ ├── Main.class
│ ├── Service.class
│ └── Utils.class
├── resources/
│ ├── config.properties
│ └── logo.png
└── META-INF/
└── MANIFEST.MF
1. 기본 JAR 생성
# 현재 디렉토리의 모든 .class 파일을 jar로 묶기
jar cf myapp.jar *.class
2. 실행 가능한 JAR 만들기
# Main 클래스가 포함된 실행 가능한 JAR 생성
jar cfe myapp.jar com.mycompany.Main *.class
3. MANIFEST.MF 파일 예시
Manifest-Version: 1.0
Main-Class: com.mycompany.Main
Created-By: 1.8.0_271 (Oracle Corporation)
# 실행 가능한 JAR 파일 실행
java -jar myapp.jar
# 특정 클래스 실행 (JAR 파일 내에서)
java -cp myapp.jar com.mycompany.Main
Spring Boot에서 Fat JAR 만들기
<!-- pom.xml -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
# 모든 의존성이 포함된 실행 가능한 JAR 생성
mvn clean package
java -jar target/myapp-1.0.0.jar
| 구분 | JDK | JRE |
|---|---|---|
| 용도 | Java 개발 | Java 실행만 |
| 포함 내용 | JRE + 개발도구 | JVM + 표준 라이브러리 |
| 대상 사용자 | 개발자 | 일반 사용자 |
개발자를 위한 완전한 도구 세트
JDK 구성요소:
├── JRE (실행 환경)
├── javac (컴파일러)
├── javadoc (문서 생성기)
├── jar (아카이브 도구)
├── javap (역어셈블러)
└── 기타 개발 도구들
Java 프로그램 실행을 위한 최소 환경
JRE 구성요소:
├── JVM (가상 머신)
├── Java 표준 라이브러리
├── java 명령어
└── 기타 실행 도구들
🖥️ 개발 환경 (로컬 PC)
# JDK 설치 필요
sudo apt install openjdk-11-jdk
# 컴파일 가능
javac HelloWorld.java
java HelloWorld
🌐 서버 환경 (배포 서버)
# JRE만 설치해도 충분
sudo apt install openjdk-11-jre
# JAR 파일 실행 가능
java -jar myapp.jar
| 항목 | JDK | JRE | JVM | JAR | JIT |
|---|---|---|---|---|---|
| 포함 내용 | • JRE 전체 • javac (컴파일러) • javadoc • jar 도구 • javap • 기타 개발 도구 | • JVM • Java 표준 라이브러리 • java 명령어 • 기타 실행 도구 | • 바이트코드 해석기 • JIT 컴파일러 • 가비지 컬렉터 • 메모리 관리자 | • .class 파일들 • 리소스 파일 • META-INF/ • MANIFEST.MF | • Hot Spot 감지기 • 기계어 컴파일러 • 코드 캐시 • 최적화 엔진 |
1. 여러 Java 버전 관리하기
# SDKMAN 사용 (추천!)
curl -s "https://get.sdkman.io" | bash
sdk install java 11.0.12-open
sdk install java 17.0.1-open
sdk use java 11.0.12-open
2. IDE에서 JDK 설정
IntelliJ IDEA:
File > Project Structure > Project SDK > Add JDK...
Eclipse:
Window > Preferences > Java > Installed JREs > Add...
JVM 메모리 사용량 확인
# 실행 중인 Java 프로세스 확인
jps -v
# 힙 덤프 생성
jmap -dump:format=b,file=heap.hprof [PID]
# GC 로그 활성화
java -XX:+PrintGC -XX:+PrintGCDetails -jar myapp.jar
자주 만나는 에러들
// 1. ClassNotFoundException
Exception in thread "main" java.lang.ClassNotFoundException: com.example.Main
해결책: 클래스패스 확인 또는 JAR 파일에 해당 클래스가 포함되어 있는지 확인
# 클래스패스 명시적 지정
java -cp ".:lib/*" com.example.Main
// 2. OutOfMemoryError
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
해결책: 힙 메모리 크기 증가
java -Xmx2g -jar myapp.jar # 최대 힙 크기를 2GB로 설정
| 도구 | 주요 명령어 | 설명 |
|---|---|---|
| JDK | javac HelloWorld.javajar cf app.jar *.classjavadoc *.java | 컴파일, 패키징, 문서 생성 |
| JRE | java HelloWorldjava -jar app.jar | 프로그램 실행 |
| JVM | -Xmx2g -Xms1g-XX:+UseG1GC | JVM 옵션 설정 |
| JAR | jar tf app.jarjar xf app.jar | JAR 내용 확인, 압축 해제 |
| JIT | -XX:+PrintCompilation-XX:CompileThreshold=1000 | JIT 컴파일 모니터링 |
Docker를 활용한 Java 애플리케이션 배포
# Dockerfile
FROM openjdk:11-jre-slim
COPY target/myapp.jar /app/myapp.jar
WORKDIR /app
EXPOSE 8080
CMD ["java", "-jar", "myapp.jar"]
# 이미지 빌드 및 실행
docker build -t myapp .
docker run -p 8080:8080 myapp
| 항목 | JDK | JRE | JVM | JAR | JIT |
|---|---|---|---|---|---|
| 설치 용량 | ~300MB | ~200MB | JRE에 포함 | 가변적 | JVM에 포함 |
| 메모리 사용 | 개발 도구별 상이 | 실행 프로그램에 따라 | 힙 + 비힙 영역 | 로딩 시에만 | 컴파일 캐시 사용 |
| 성능 영향 | 개발 속도 향상 | 기본 실행 성능 | 전체 성능 기반 | 로딩 시간 단축 | 실행 성능 대폭 향상 |