클래스 로더(Classloader)
- 이름을 알고 있는 특정 클래스에 대한 정의(Bytestream)를 가져오는 역할을 수행
- 부트스트랩 클래스 로더
- JVM에서 라이브러리로 취급(
rt.jar
, tools.jar
)되는 것들을 로드 (핫스팟에서는 C++로 구현)
- 플랫폼 클래스 로더 (기존 확장 클래스 로더)
- 애플리케이션 클래스 로더
sun.misc.Launcher$AppClassLoader
를 의미
Java 클래스 로딩

클래스 파일 형식
- Java 소스(
.java
)는 컴파일되어 바이트 스트림을 포함한 .class
파일이 됨
.class
파일은 클래스의 형식과 버전 정보를 포함
오류 유형
- 컴파일 타임 오류: 문법적 오류
- 런타임 오류: 프로그램 실행 중 발생하는 오류 (Linking 과정 포함)
C++과의 차이점
- Java는 생성자만 존재하고 소멸자 개념이 없음
- 객체 소멸은 GC가 자동으로 관리
Linking 과정
Initialization 시점에 도달하고 나서야 생성자 호출
Linking과정이 지나야 생성자가 호출된다.
- Verification 검증
- Preparatino 준비
- Resolution 해석

- 클래스 로딩 및 링킹 과정이 모두 런타임에 이뤄짐
- 실행 성능이 일부 저하될 수 있으나 높은 확장성과 유연성을 제공하는 공간
- 인터페이스만 맞으면 Runtime에 구현 클래스를 결정하지 않을 수 있음
- 클래스 로더는 실행할 프로그램 코드를 네트워크로 수신하는 것도 가능
- 해석(Resolution) 단계는 동적 바인딩(혹은 늦은 바인딩)을 지원할 목적으로 초기화 후로 지연될 수 있음
검증 (Verification)

심벌 참조 검증
- 상속 관계와 의존성을 확인하는 심벌 참조는 다음과 같이 동작한다:
- 자식 클래스가 부모 클래스에 대해 존립 수준의 의존성을 가질 때, 부모 클래스가 먼저 로딩되어야 한다
- 예시로
MyTestEx
클래스는 MyTest
클래스에 의존적이므로 MyTest
가 먼저 로딩되어야 한다.
- 메서드 호출, 상속 관계, 클래스 로딩 순서등의 정보를 포함한다.
바이트코드 실행과 메모리
- 바이트 코드 실행 시:
- 실행 코드는 메모리의 특정 위치에 저장
- 실제 메모리 위치 정보를 찾아 바인딩
- 이를 통해 메서드 호출과 연산이 가능해진다.
- 실행 시 필요한 클래스, 메서드, 필드 등의 모든 논리적 참조 정보를 하이레벨 언어 수준에서 심볼로 표현한 것이 심볼 참조다.
보안 검증
- JVM은 보안을 위해 다음을 수행한다
- 바이트코드 레벨에서 보안 위협 검사
- OS에 영향을 미칠 수 있는 코드 검증
- 이 과정은 시간이 많이 소요되는 심층적인 검증 과정

jvm이 한정하는 영역을 못벗어나도록 애플리케이션을 제한한다.
이런 요소때문에 보안과 관련해 C나 C++ 보다 훨씬 안정적이다
준비(Preparation) 및 해석(Resolution)

- 객체 인스턴스가 저장될 메모리 공간을 확보하고 0으로 초기화
- 생성자 호출 전 상태 (필드 초깃값은 생성자 호출 시 변경)
- 해석은 상수 풀의 심벌 참조를 직접 참조로 대체하는 과정
메모리 구조
- 참조 변수
t
는 스택 영역에 저장
- 실제 객체 인스턴스는 힙 영역에 저장
- 예시:
MyTest t = new MyTest
t
는 Stack에 위치한 참조 변수
- 실제 객체는 Heap 영역에 위치
- 참조 변수는 힙의 객체 주소를 가리킴
초기화와 생성자
jvm은 인스턴스가 저장될 공간을 몽땅 확보하고 0 초기화 한다.
Field에 0을 초기화(Field = 0;
)하지 않아도 기본적으로 0 초기화를 시행한다.
메모리가 준비되면, 이는 아직 생성자가 호출되기 전이다.
따라서 필드 초깃값은 생성자에서 바꾸면 그게 우선한다.
메모리 준비가 끝나고 초기화 되면서 생성자가 호출될 때, 메모리의 값을 가서 조작한다.
해석(Resolution) 과정
- 심볼릭 참조를 실제 메모리 참조(직접 참조)로 변환하는 과정
- (참조) 이 과정을 특이하게 해석이라고 부른다.
- 메서드나 필드 호출 시 실제 메모리 위치를 찾아 바인딩
- 모든 참조가 실제 메모리 위치와 연결되는 과정 수행
해석 단계에서 의존관계에 있는 다른 클래스 로딩 여부를 결정하는데, 이 때 실패하면 의존성 있는 클래스를 못가져와서 로딩 실패가 발생한다.
Preparation은 메모리 확보 및 메타데이터 집어넣는 작업을 수행하는데, 이 내부에서 어떤 내용들이 이뤄지는지만 알고, GC가 어떻게 활용하는지만 알면 될 것 같다.
Initialization(사용 직전 단계)에서 생성자 호출하고, 사용단계로 넘어간다. 클래스가 Unloading되는 시점은 가비지 컬렉터가 결정할 일이기 때문에 자바에서는 이 부분에 개입하지 않는 것이 잘하는 것이다.
Heap 영역에 객체 생성

- JVM은 객체 저장을 위한 메모리 공간을 확보 후 0으로 초기화 (단, 객체 헤더 제외)
- 객체 초기화를 위한 구성설정 실시
- 클래스 이름 및 메타 정보 확인 방법
- 객체에 대한 해시코드
- GC 세대 나이
- 생성자 호출
객체 구조
- 인스턴스의 두 주요 영역
- 실제 데이터 영역: 인스턴스 필드 정보 저장
- 메타 데이터 영역: 객체 관리 정보, GarbageCollector, 동시성 이슈 lock 관련 정보까지도 저장
메타 데이터 구성 요소
- 클래스 이름 및 메타 정보
- 해시코드 (인스턴스 식별용 고유값)
- 인스턴스의 나이 (GC 관련)
- Garbage Copllection 관련 정보
- GC가 인스턴스의 메모리 위치를 옮길 때 나이를 기반으로 collecting 가능성을 고려하며 옮긴다.
- 동시성 제어를 위한 lock 정보
초기화 프로세스
- 메모리 확보 및 0 초기화
- 메타 데이터 값 넣어주어 설정
- 클래스 준비 완료
<init>
메서드를 통해 생성자 호출
- 필드 초기화

이런 Java 객체 레이아웃, 구조를 Java Object Layout이라고 부른다.