[F-Lab 66해빗 페이백 챌린지 ]
[F-Lab 페이백 모각코 63일차] 클래스 로더 (Class Loader)
everydeveloper
2023. 9. 9. 23:45
- Class Loader
- 계층 구조
- 부트스트랩 클래스 로더 (Bootstrap Class Loader)
- 확장 클래스 로더 (Extension Class Loader)
- 애플리케이션 클래스 로더 (Application Class Loader)
- 로딩
- 클래스 로더가 해당 클래스의 바이트코드를 찾아 메모리에 로드합니다. 이 과정에서 클래스 로더 계층 구조를 따르며, 로드된 클래스는 메소드 영역에 저장됩니다.
- 로딩순서
- 애플리케이션 클래스 로더 (Application Class Loader)
- 확장 클래스 로더 (Extension Class Loader →Platform ClassLoader(Java9부터))
- 부트스트랩 클래스 로더 (Bootstrap Class Loader)
- 연결
- 검증
- 형식 검사: 클래스 파일의 매직 넘버, 파일 버전, 상수 풀, 바이트코드 크기 등이 올바른 형식을 갖추고 있는지 확인합니다.
- 매직 넘버 검사 : 클래스 파일이 올바른 매직 넘버(0xCAFEBABE)로 시작하는지 확인합니다. 매직 넘버는 파일이 자바 클래스 파일임을 식별하는 데 사용됩니다.
- 버전 검사 : 클래스 파일의 메이저(major)와 마이너(minor) 버전이 JVM에서 지원하는 버전 범위 내에 있는지 확인합니다.
- 상수 풀 검사 : 클래스 파일 내의 상수 풀이 올바른 구조를 가지고 있는지 확인하고, 각 상수 풀 항목이 올바른 타입을 갖추고 있는지 확인합니다.
- 클래스 정보 검사 : 클래스 파일의 클래스 및 인터페이스 정보가 올바르게 정의되어 있는지 확인하고, 클래스 이름, 슈퍼클래스 이름, 인터페이스 이름 등이 올바른 형식을 갖추고 있는지 검사합니다.
- 필드와 메소드 검사 : 클래스 파일의 필드와 메소드가 올바르게 정의되어 있는지 확인하고, 필드와 메소드의 이름, 시그니처, 접근 제어자 등이 올바른 형식을 갖추고 있는지 검사합니다.
- 바이트 코드 검사 : 클래스 파일의 바이트코드가 올바르게 구성되어 있는지 확인하고, 바이트코드 명령어들이 올바른 크기와 형식을 갖추고 있는지 검사합니다.
- 내부 검사: 클래스 파일의 내부 구조가 올바르게 정의되어 있는지 확인합니다. 예를 들어, 상속 관계의 일관성, 메소드와 필드의 시그니처, 코드 내의 스택 맵 프레임 등을 검사합니다.
- 필드와 메서드의 플래그 검사: 필드와 메서드는 각각 고유한 플래그를 가집니다. 이 플래그는 접근 제어자와 같은 특성을 나타냅니다. 내부 검사는 이러한 플래그가 올바르게 설정되었는지 확인합니다. 예를 들어, 인터페이스에 대한 플래그가 클래스에 대한 플래그와 충돌하지 않아야 합니다.
- 상속 관계 검사: 클래스와 인터페이스 간의 상속 관계가 올바르게 구성되어 있는지 확인합니다. 이 검사는 다중 상속이 발생하지 않도록 하며, 인터페이스가 올바르게 구현되었는지 확인합니다.
- 순환 상속 검사: 클래스나 인터페이스 간에 순환 상속이 발생하지 않아야 합니다. 순환 상속은 한 클래스가 자신을 직접 또는 간접적으로 상속하게 되는 상황을 말합니다. 검증 과정에서 이러한 상황을 확인하고 방지합니다.
- 자바는 클래스 간의 다중 상속을 허용하지 않습니다. 검증 과정에서 클래스가 둘 이상의 클래스를 상속하려고 하는지 확인하고 이를 방지합니다. 인터페이스의 경우 다중 상속이 허용되므로, 이에 대한 검사는 수행되지 않습니다.
- 다중 상속 검사: 자바는 클래스 간의 다중 상속을 허용하지 않습니다. 검증 과정에서 클래스가 둘 이상의 클래스를 상속하려고 하는지 확인하고 이를 방지합니다. 인터페이스의 경우 다중 상속이 허용되므로, 이에 대한 검사는 수행되지 않습니다.
- 인터페이스 구현 검사: 클래스가 인터페이스를 올바르게 구현했는지 확인합니다. 이 검사는 클래스가 인터페이스의 모든 메서드를 제공하고 있는지, 그리고 이러한 메서드가 올바른 시그니처와 접근 제어자를 가지고 있는지 확인합니다.
- 추상 클래스와 인터페이스 검사: 추상 클래스는 객체를 직접 생성할 수 없으며, 하위 클래스를 통해서만 사용할 수 있습니다. 검증 과정에서 추상 클래스의 인스턴스화를 방지합니다. 또한 인터페이스는 상속 구조에서 특별한 위치를 차지하므로, 인터페이스에 대한 추가 검사를 수행합니다.
- 메서드 오버라이딩 검사: 하위 클래스가 상위 클래스의 메서드를 올바르게 오버라이딩하고 있는지 확인합니다. 이 검사는 메서드의 시그니처와 반환 타입이 일치하는지 확인하며, 접근 제어자와 관련된 규칙을 준수하는지 확인합니다.
- 참조 검사: 클래스 파일 내에서 참조되는 필드, 메서드, 클래스, 인터페이스 등이 올바르게 정의되어 있는지 확인합니다. 이 검사는 유효하지 않은 참조가 발생하지 않도록 합니다.
- 애트리뷰트 검사: 클래스 파일에 포함된 다양한 애트리뷰트(예: 코드, 로컬 변수 테이블, 예외 테이블 등)가 올바르게 구성되어 있는지 확인합니다. 이 검사는 각 애트리뷰트의 길이와 내용이 올바른지 확인합니다.
- 의존성 검사: 클래스 파일이 참조하는 다른 클래스나 인터페이스가 존재하고 올바른지 확인합니다.
- API 제약 검사: 클래스 파일이 자바 가상 머신의 API 제약을 준수하는지 확인합니다. 예를 들어, final 키워드를 사용한 클래스가 상속되지 않게 하거나, 인터페이스 메소드가 올바르게 구현되었는지 검사합니다.
- 형식 검사: 클래스 파일의 매직 넘버, 파일 버전, 상수 풀, 바이트코드 크기 등이 올바른 형식을 갖추고 있는지 확인합니다.
- 준비(Preparation)
- 정적 변수의 메모리 공간을 할당
- 각 정적 변수에 해당하는 데이터 타입의 기본값을 할당
- ex) int: 0. boolean은 false, 참조형은 null
- 실행(Resolve)
- 클래스나 인터페이스의 상징적인 이름을 사용하여 해당 클래스나 인터페이스를 찾습니다.
- 필드와 메소드에 대한 상징적인 참조를 찾아서 해당 필드나 메소드를 찾습니다.
- 상징적인 참조(symbolic reference)는 클래스, 인터페이스, 필드, 메소드 등을 표현하는데 사용되는 고유한 식별자를 의미합니다. 이 식별자는 컴파일된 클래스 파일 내에서 참조 대상을 가리키는 방법으로 사용되며, JVM이 클래스 로딩 과정에서 이를 실제 메모리 주소나 다른 직접 참조로 변환해야 합니다.
- 찾은 클래스, 인터페이스, 필드, 메소드의 실제 메모리 주소나 다른 직접 참조로 상징적인 참조를 대체합니다.
- 검증
- 초기화
- 정적 변수의 초기 값 할당
- 정적 변수에 대해 선언 시 지정된 초기 값을 할당합니다. 초기 값이 지정되지 않은 경우, 해당 변수의 타입에 따라 기본값이 할당됩니다(예: 숫자형 변수는 0, 참조형 변수는 null).
- 정적 블록의 실행
- 정적 블록은 클래스가 로드될 때 한 번만 실행되는 코드 블록입니다. 정적 블록은 클래스의 정적 변수를 초기화하거나 복잡한 연산을 수행하기 위해 사용될 수 있습니다.
- 초기화 단계를 클래스 로딩 과정에서 한번 만 수행되며, 초기화가 완료된 후에는 클래스의 정적 구성 요소가 프로그램에서 사용될 수 있습니다. 클래스 초기화는 클래스가 처음으로 실제로 사용되는 시점에 수행되므로, 프로그램 시작 시점이 아닌 실행 도중에 수행될 수도 있습니다.
- 정적 변수의 초기 값 할당
- 계층 구조
[Java] 자바 클래스로더(Class Loader)
자바언어로 작성된 클래스 파일은 JVM 위에서 동작한다. 직접 운영체제 위에서 동작하지 않기 때문에 높은 이식성을 가질 수 있게되었다. 자바의 클래스로더(ClassLoader)는 컴파일된 클래스 파일을
hbase.tistory.com