hyeonga_code

JVM_09_클래스 로딩 Class Loading 본문

JVM

JVM_09_클래스 로딩 Class Loading

hyeonga 2024. 5. 8. 13:59
반응형

클래스 로딩 Class Loading

JVM의 클래스 로더가 자바 애플리케이션을 실행하는 데 필요한 .class 파일을 로드하고 링크하며 초기화하는 과정을 의미합니다.

Class Loading
  1. Loading
  2. Linking
  3. Initialization
      - Dynamic Loading
      - Static Loading

1. 로딩 Loading

파일 시스템이나 네트워크 소스에서 지정된 클래스 파일을 찾아 읽습니다.
이 파일은 자바 소스코드를 컴파일하여 생성된 바이너리 데이터인 바이트코드를 포함합니다.
읽은 바이트코드는 메소드 영역에 저장됩니다.

.class 파일을 메모리에 로드하는 과정으로 클래스 로더를 사용하여 파일 시스템, 네트워크, 아카이브 파일 내에서 파일이 위치한 곳을 찾습니다.
클래스를 찾지 못한 경우에는 상위 로더로 요청을 위임_deligation 하게 됩니다.
파일을 찾은 경우 파일에 포함된 바이트코드를 메모리로 가져와 JVM의 안전 요구사항(코드의 형식화, 메모리 엑세스, 안전성 확인 등)을 만족하는지 검사합니다.
런타임 데이터 영역에 클래스를 저장하여 검증된 바이트코드는 JVM의 메소드 영역에 저장합니다.
클래스 로더 구성 부트스트랩 클래스 로더 확장 클래스 로더 시스템/애플리케이션 클래스 로더

2. 링킹 Linking

로드된 클래스의 바이트코드를 JVM이 실행할 수 있도록 준비하는 과정으로 바이트코드가 JVM의 사양에 맞게 형성되었는지 검증하여 메모리의 오류나 보안 위반을 예방합니다.
정적 데이터에 대한 메모리를 할당하고 기본값으로 초기화하는 준비 과정을 거쳐 클래스, 인터페이스, 필드, 메소드에 대한 심볼릭 메모리 참조를 메소드 영역의 실제 참조로 변환하는 해석단계를 거칩니다.

동적 링킹

주로 로딩된 클래스를 JVM이 실행할 수 있도록 준비하고 연결하는 과정에서 일어납니다.
링킹 과정에는 검증, 준비, 해석의 과정이 수행됩니다.

 

1) 검증 Verification
JVM이 클래스를 사용하기 전에 안전성을 보장하기 위한 필수적인 요소입니다.


- 형식 검증 :
로드된 바이트코드가 적절한 형식과 구조를 갖추고 있는지 확인합니다.
파일이 유효한 '.class' 파일 포맷을 따르는지 확인합니다.


- 규칙 검증 :
바이트코드가 자바 언어 명세와 JVM 명세에 맞게 작성되었는지 확인합니다.
변수에 할당되지 않은 값이 사용되지 않도록 하고, 스택오버플로우나 언더플로우가 발생하지 않도록 합니다.


- 구조적 검증 Structural Verification :
클래스의 구조적 측면이 JVM 규격에 부합하는지를 검사합니다.
final로 선언된 클래스가 다른 클래스에 의해 상속되지 않도록 합니다.

 

>> 예시
1) 상속 규칙 검사
public final class MyFianlClass는 상속될 수 없으며 이를 상속하려는 시도가 있는 경우 검증 단계에서 오류가 발생합니다.
JVM은 서브 클래스에서 오버라이드된 메소드가 슈퍼 클래스의 메소드와 호환되는지 검사합니다.

 

2) 메소드 오버라이딩 검사
접근 제어자를 더 제한적으로 변경하거나 반환 타입을 호환되지 않게 변경하는 등의 오류를 찾아냅니다.

 

3) 인터페이스 구현 검사
클래스가 인터페이스를 올바르게 구현하고 있는지 확인합니다.
모든 인터페이스 메소드가 클래스에 구현되어 있어야 하며, 시그니처와 반환 타입이 일치해야 합니다.

 

2) 준비 Preparation
클래스나 인터페이스에 필요한 메모리를 할당하고 정적 필드를 기본값으로 초기화 합니다.
모든 정적 필드에 대한 메모리 공간을 할당하고, 이 공간은 메소드 영역에 생성됩니다.
할당된 메모리 공간에 대해 각 필드를 자바 데이터 타입의 기본값으로 초기화합니다.

 

3) 해석 Resolution
클래스, 인터페이스, 필드, 메소드의 심볼릭 참조를 실제 참조로 변환하는 과정입니다.
필요에 따라 런타임에 수행될 수 있습니다.
클래스의 바이트코드 내에서 다른 클래스나 메소드, 필드 등을 참조할 때 사용되는 심볼릭 이름을 JVM 내의 실제 주소나 참조로 매핑합니다.
해석 단계에서 JVM은 클래스 파일 내의 심볼릭 참조를 해석하기 위해 먼저 클래스 로더를 통해 해당 참조가 가리키는 클래스나 리소스가 로드되어 있는지를 확인합니다. 메모리에 없는 경우 클래스 로더를 사용하여 해당 요소를 찾고 로드하는 참조 식별과 검색 과정을 수행합니다.
참조가 성공적으로 해석되면 JVM은 해당 메소드나 필드, 클래스에 접근이 허용되는지를 클래스의 접근 제어자를 통해 결정합니다.

 

참조 접근성 검사 Accesibility 

클래스, 메소드, 필드 등의 심볼릭 참조를 실제 참조로 변환할 때 수행되는데 이 과정에서 JVM은 접근성 검사를 수행하여 안전성을 확보합니다.
접근 제어자를 확인하여 접근할 수 있는지를 확인합니다.
패키지 내부에서만 접근 가능한 클래스나 멤버에 대해 다른 패키지에서 접근하려는 시도를 차단합니다.
클래스의 설계 의도에 따라 적절한 캡슐화와 정보 은닉을 보장합니다.
클래스 외부에서 내부 구현에 무분별하게 접근하는 것을 방지하여 객체의 무결성을 유지하는 데 도움이 됩니다.

3. 초기화 Initialization

처음 참조되는 경우 정적 변수 초기화로 클래스 변수가 정의된 초기값으로 설정됩니다.
클래스 로딩 과정에서 정적 블록이 있는 경우에만 블록을 실행합니다.
초기화는 해당 클래스가 처음으로 참조될 때 단 한 번만 수행됩니다.

정적변수 초기화
정적블록 실행

정적 변수 초기화

클래스 변수가 정의된 초기값으로 설정됩니다.
클래스 로더가 클래스를 로드한 후 링킹 단계를 통과한 클래스에 대해 수행됩니다.
초기화는 해당 클래스가 처음으로 참조될 때 단 한번만 수행됩니다.

정적 블록 실행

클래스 로딩 과정에서 정적 블록이 있는 경우에만 실행합니다.
변수를 초기화하거나 시작 시 실행해야 하는 코드를 포함할 수 있습니다.
클래스의 인스턴스가 생성될 때나 정적 메소드를 호출하는 경우 실행됩니다.
정적 필드에 접근하거나 리플렉션을 통한 접근도 포함됩니다.

반응형