자바 클래스 로더
자바 프로그램은 한 개 혹은 그 이상의 클래스들의 조합으로 실행됩니다. 그리고 실행 시 모든 클래스 파일이 한 번에 로딩되지 않고 요청되는 순간 로딩됩니다.
자바의 클래스 로더는 자바의 큰 장점 중 하나로 컴파일타임이 아닌 런타임에 Class를 로딩할 수 있게해주는 기술입니다. 바이트 코드를 읽어 들여 class 객체를 생성하는 역할을 담당합니다. 즉, 클래스 로더는 클래스가 요청될 때 파일로부터 읽어 메모리로 로딩하는 역할을 하며 자바 가상 머신의 중요한 요소 중 하나입니다. 자바 런타임 환경(JRE)의 일부입니다.
클래스 로더는 Loading, Linking, Intialize의 순서로 진행됩니다.
로딩( Loading )
클래스 로더가 .class 파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 메서드 영역에 저장합니다. (메서드 영역에 저장하는 데이터는 FQCN(Full Qualified Class Name), 클래스, 인터페이스 , Enum, 메서드와 변수) **로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여 힙 영역에 저장합니다.
연결 ( Linking )
Verify(검증), Prepare(준비), Resolve(실행) 세 단계로 나누어져 있습니다. 검증단계(verify)는 .class 파일의 정확성을 확인합니다. (Java 언어 사양에 따라 코드가 올바르게 작성되었는가? JVM 사양에 따라 유효한 컴파일러에 의해 생성되는가?) 가장 복잡한 과정이며, 가장 오랜 시간이 걸립니다. 연결로 인해 클래스 로딩 프로세스가 느려지더라도 바이트 코드를 실행할 때 이러한 검사를 여러 번 수행할 필요가 없으므로 전체적인 실행이 효율적이고 효과적입니다. 검증이 실패하면 런타임 오류(java.lang)를 발생시킵니다. 준비단계(Preparation)는 JVM은 메모리를 기본 값으로 초기화 한 후, 클래스 변수들을 위한 메모리에 할당합니다. 실행단계(Resolve)는 심볼릭 메모리 래퍼런스를 메서드 영역에 있는 실제 레퍼런스로 교체합니다.
초기화 ( Initialize )
클래스나 인터페이스의 초기화 로직을 실행합니다.
클래스 로더란?
Bootstrap Class Loader
부트스트랩 클래스로더는 3가지 기본 클래스로더 중 최상위 클래스로더 입니다. jre/lib/rt.jar에 있는 JVM을 실행시키기 위한 핵심 클래스들을 로딩합니다. Native C로 작성되어 있습니다.
Java9부터 rt.jar, tools.jar 등 기본으로 제공되던 jar 파일이 없어지고 그 안에 있던 내용들은 모듈 시스템에 맞게 더 효율적으로 재편되어 lib 폴더 안에 저장됩니다. 이에 따라 rt.jar내의 모든 클래스를 로딩할 수 있던 Bootstrap ClassLoader가 로딩할 수 있는 클래스의 범위도 전체적으로 줄어들었습니다. 따라서 Bootstrap ClassLoader를 parent classloader로 사용하던 코드에서는 문제가 발생할 수 있습니다.
Extensions ClassLoader
jre/lib/ext 폴더나 java.ext.dirs 환경 변수로 지정된 폴더에 있는 클래스 파일을 로딩합니다.
Java의 확장 클래스 파일들을 로드합니다.
URLClassLoader를 상속 받습니다.
Java9부터는 Platform ClassLoader로 명칭이 변경됩니다. Java SE의 모든 클래스와 Java SE에는 없지만 JCP에 의해 표준화 된 모듈 내의 클래스를 볼 수 있으며, Java 8에 비해 볼 수 있는 범위가 확장되었습니다. 또 jre/lib/ext, lib/endorsed, java.ext.dirs, java.endorsed.dirs 가 제거되었습니다. jre/lib/ext, lib/endorsed가 파일시스템에 존재하거나 java.ext.dirs, java.endorsed.dirs가 환경변수로 설정되어 있으면 실행이 종료됩니다. BuiltinClassLoader를 상속 받도록 변경됩니다.
Application ClassLoader
명시된 경로(class path에 정의되거나 JVM 옵션에서 -cp, -classpath에 지정된)에서 코드를 로딩하는 클래스로더입니다.
애플리케이션 구동을 위해 직접 작성한 대부분의 클래스는 이 애플리케이션 클래스로더에 의해 로딩됩니다.
URLClassLoader를 상속하고 있습니다.
Java9부터는 System ClassLoader로 명칭이 변경됩니다. BuiltinClassLoader를 상속 받도록 변경됩니다.
클래스 로더의 특징
위임원칙 ( Delegation Principle )
새로운 클래스의 로딩 요청이 있을 때, 상위 로더에게 우선 클래스 로딩을 위임합니다.
- ClassLoaderRunner는 자기 자신을 로딩한 Application ClassLoader에게 Internal 클래스 로딩을 요청합니다.
- 그렇게 되면 Application ClassLoader는 Internal을 상위의 Extension ClassLoader에게 위임합니다.
- 다시 Extension ClassLoader는 Internal을 최상위의 Bootstream ClassLoader에 위임합니다.
- 이제 최상위에 도달하게 되면 Internal에 대해 일치하는 클래스가 있으면 클래스를 반환하고, 없을 경우 하위에 다시 전달하도록 진행됩니다.
- 최하단의 Applcation ClassLoader도 찾기 못할 경우 ClassNotFountException이 발생하게 됩니다.
가시 범위 원칙 (visibility principle)
하위 클래스 로더는 상위 클래스 로더가 로딩한 클래스를 볼 수 있습니다.
상위 클래스 로더는 하위 클래스 로더가 로딩한 클래스를 볼 수 없습니다다.
유일성 원칙 (uniqueness princile)
하위 클래스 로더는 상위 클래스 로더가 로딩한 클래스를 다시 로딩하지 않게 합니다.
이를 통해 로딩된 클래스의 유일성을 보장합니다.
클래스 언로드 불가 (Cannot Unload Classes)
클래스 로더에 의해 로딩된 클래스는 언로드(unload)될 수 없고 그 클래스를 로딩한 클래스 로더가 삭제될 때까지 유지됩니다. 그렇기에 언로딩을 하기 위해선 ClassLoader 자체를 삭제하고, ClassLoader을 다시 생성하는 방법이 있습니다.
'Language > Java' 카테고리의 다른 글
[Java] 제네릭 (Generic) (0) | 2021.04.21 |
---|---|
[Java] 다형성 (0) | 2021.01.01 |
[Java] 실행 데이터 영역 (Runtime Data Area) (0) | 2020.12.27 |
[Java] 자바란? ( Java ) (0) | 2020.12.25 |
[Java] JVM Architecture (0) | 2020.06.07 |
댓글