반응형
공부시작!
1. 클래스 로딩 시점
JVM은 클래스를 "필요한 순간"에 로딩합니다. 정확한 시점은 아래와 같습니다:
- 클래스를 사용할 때: 예를 들어, new 키워드로 객체를 생성하거나, 클래스의 정적 메서드/변수를 호출할 때.
- Class.forName() 호출 시: 리플렉션을 통해 클래스를 로드할 때.
- JVM의 기본 실행: JVM이 시작되면서 메인 클래스를 로드합니다.
2. 클래스 로딩 처리 과정 (3단계)
클래스 로딩은 크게 로딩 → 링크 → 초기화의 3단계로 나뉩니다.
(1) 로딩 (Loading)
- 클래스 파일(.class)을 찾고 읽어들여 메모리에 로드합니다.
- 이 작업은 JVM 내의 클래스 로더(ClassLoader)가 담당합니다.
- 메서드 영역에 클래스 정보를 저장 합니다.
- 클래스 객체(java.lang.Class)를 생성 합니다.
(2) 링크 (Linking)
- 검증(Verification): 바이트코드 검증
- 클래스 파일이 유효한지 검증합니다.
- JVM 스펙에 맞지 않으면 VerifyError 발생.
- 준비(Preparation): static 변수 메모리 할당, 기본값으로 초기화
- 클래스의 정적 변수(static fields)를 메모리에 할당하고 기본값(0, null 등)으로 초기화.
- 해결(Resolution): 심볼릭 레퍼런스를 실제 레퍼런스로 교체
- 클래스 내부에서 참조하는 다른 클래스(예: 상속받는 클래스, 메서드 호출 등)를 확인하고 연결.
(3) 초기화 (Initialization)
- 클래스의 정적 변수에 명시된 값으로 초기화하고, 정적 초기화 블록(static {})을 실행합니다.
3. 클래스 로더 (Class Loader)
JVM에는 여러 클래스 로더가 계층적으로 동작합니다.
주요 클래스 로더와 역할은 아래와 같습니다:
- Bootstrap ClassLoader
- 가장 기본적인 클래스 로더로, JDK 내부의 핵심 클래스(java.lang, java.util 등)를 로드.
- C++로 구현되어 있음.
- Extension ClassLoader
- JAVA_HOME/lib/ext 폴더에 있는 확장 클래스들을 로드.
- Application ClassLoader
- 애플리케이션 코드(classpath 경로의 클래스)를 로드.
- 사용자가 작성한 클래스와 외부 라이브러리(JAR 파일)도 여기에 포함됨.
- Custom ClassLoader
- 사용자가 직접 정의하여 동작을 변경할 수 있는 클래스 로더.
- 주로 애플리케이션에서 특정 파일 구조나 동적 로딩이 필요할 때 사용.
4. 자바 모듈 시스템 (Java 9 이상)
자바 모듈 시스템은 JAR 파일의 단점을 보완하기 위해 등장했습니다.
주요 목적은 모듈화, 캡슐화, 의존성 관리입니다.
주요 특징
- 모듈 정의
- 각 모듈은 module-info.java 파일로 정의됩니다.
- 예:
module com.example.myapp {
requires java.sql; // 의존 모듈
exports com.example.myapp.services; // 외부에 공개할 패키지
}
- 의존성 관리
- 컴파일 시점에 필요한 모듈과 런타임에 필요한 모듈을 명시적으로 선언 가능.
- 불필요한 모듈 접근 차단.
- 강한 캡슐화
- 모듈 외부에서 특정 패키지에 접근하지 못하도록 제한.
- JVM의 작은 런타임 지원
- 필요한 모듈만 포함하는 맞춤형 런타임 이미지 생성 가능 (jlink 사용).
장점
- 애플리케이션 크기 감소.
- 코드 가독성 향상.
- 유지보수성 개선.
- 강력한 캡슐화: 모듈 내부 구현 숨김
- 명시적 의존성: requires로 필요한 모듈 선언
- 서비스 지향: provides/uses로 서비스 구현
- 플랫폼 모듈화: JDK 자체가 모듈화됨
단점
- 초기 도입 시 복잡성 증가.
- 기존의 JAR 중심 프로젝트와 호환성을 맞추는 데 추가 작업 필요.
추가로 정리한 부분입니다.
JIT 컴파일러 (Just-In-Time Compiler)
- JVM은 바이트코드(.class 파일)를 런타임에 기계어로 번역해서 실행합니다.
- 이 번역 작업을 효율적으로 하기 위해 JIT 컴파일러가 동작합니다.
- 자주 실행되는 코드(핫스팟)는 JIT이 최적화해 더 빠르게 실행되도록 만들어줍니다.
왜 중요한가?
- JVM 성능을 높이는 핵심 요소입니다.
- 최적화 전략 때문에 코드 실행 속도가 예상보다 빠르거나 느릴 수 있음.
Class.forName()과 ClassLoader 차이
둘 다 클래스를 로드하지만, 차이점이 있어요.
- Class.forName("클래스명"): 클래스를 로드 + 초기화까지 진행.
- ClassLoader.loadClass("클래스명"): 클래스를 로드만 진행(초기화는 나중에).
언제 사용할까?
- 리플렉션이나 동적 로딩을 사용할 때 ClassLoader로 필요한 시점에만 로딩 가능.
컴파일과 인터프리트
- 자바는 컴파일 언어이자 인터프리트 언어입니다.
- 컴파일: 자바 코드를 바이트코드(.class)로 변환.
- 인터프리트: JVM이 바이트코드를 기계어로 번역하며 실행.
HotSpot JVM의 튜닝
- JVM은 실행 시 여러 옵션으로 튜닝 가능합니다.
- -Xmx: 힙 메모리의 최대 크기 설정.
- -XX:+UseG1GC: GC 알고리즘 변경(G1 GC 사용).
- -XX:+PrintGCDetails: GC 로그 출력.
- 대규모 프로젝트에서 성능을 최적화할 때 매우 중요합니다.
반응형
'public void static main > Book' 카테고리의 다른 글
[대규모 시스템 설계 기초] 3장, 4장 (1) | 2025.01.08 |
---|---|
[대규모 시스템 설계 기초] 1장, 2장 (1) | 2025.01.06 |
[JVM 밑바닥] 6장 클래스 파일 (1) | 2024.10.27 |
[JVM 밑바닥] 3장 가비지 컬렉터와 메모리 할당 전략 -1 (0) | 2024.08.07 |
[JVM 밑바닥] 1장. 자바, 2장 자동 메모리 관리 (6) | 2024.07.25 |
댓글