클래스파일을 읽는 과정
- 로딩
- 링크
- 초기화
로딩(Loading)
클래스 로더가 .class 파일을 읽고나서 알 수 있는 정보들을 메모리에 저장하는 단계.
.class파일에서 알 수 있는 정보는 다음이 존재한다.
- 클래스
- 메소드
- 변수
- 인터페이스
- Enum
- FQCN (Fully Qualified Class Name)
- ex : java.lang.String
메소드와 변수는 클래스내부에 존재하며, 인터페이스와 Enum은 전부 클래스의 일종이라고 볼 수 있기 때문에 로딩이 종료되면 클래스타입의 객체를 Heap 영역에 저장한다.
Class Loader ( 클래스 로더 )
클래스를 읽어들이는 일을하며, 클래스의 타입과 경로에 따라 특정 클래스를 로드하는 ClassLoader 가 결정된다.
클래스로더를 알아내기 위해서 getClassLoader() 메소드가 사용되며, 최상위 클래스로더부터 클래스를 읽어들이는 과정에서 해당 클래스를 찾지못하면 ClassNotFoundException이 발생한다.
클래스로더는 크게 3가지로 나뉘게되며 각각 상속관계에 있다.
BootStrap 클래스로더
- $JAVA_HOME\lib에 있는 jar파일을 대상으로하는 최상위 우선순위의 클래스로더.
Extension(= Platform) 클래스로더( 1번을 상속 )
- JAVA_HOME\lib\ext 또는 java.ext.dirs 시스템 변수에 해당하는 위치의 클래스를 읽는다.
Application 클래스로더( 2번을 상속 )
- 애플리케이션 실행 시 주어지는 -classpath 옵션이나 환경변수 CLASSPATH값에 해당하는 위치에서 클래스를 읽는다.
최상위 클래스로더부터 순서대로 읽으면서 탐색한다.
public class Masulsa {
public static void main(String[] args) {
ClassLoader classLoader = Masulsa.class.getClassLoader();
System.out.println(classLoader);
System.out.println(classLoader.getParent());
System.out.println(classLoader.getParent().getParent());
}
}
== 출력 결과 ==
sun.misc.Launcher$AppClassLoader@18b4aac2 // Application 클래스로더
sun.misc.Launcher$ExtClassLoader@f0f2775 // Extension 클래스로더
null // Bootstrap 클래스로더지만 확인불가능
링크(Linking)
Verify, Preapare, Resolve 세 단계로 나뉘어서 이루어진다.
Verify ( 확인 )
- 생성된 바이트코드가 정상적인지 확인
Prepare ( 준비 )
- 모든 static 변수에 대해 메모리를 할당하고 기본값을 세팅
Resolve ( 해결 )
- 모든 Symbolic 메모리 참조를 Method영역의 참조로 변경
초기화 (Initialization)
모든 static 변수의 값들을 할당하고 static 블럭을 실행시킨다.