동작원리
Java의 동작 원리를 알기 위해서는 JDK,JRE,JVM을 알아야 합니다.
- JDK ( Java Development Tool)
Java 응용 프로그램 개발 및 실행에 사용되는 완전한 개발 환경. JRE 및 개발 도구가 모두 포함되어 있습니다. - JRE ( Java Runtime Environment )
Java 애플리케이션을 실행하는 데 필요한 JVM (Java Virtual Machine) 및 자바 클래스 라이브러리(Java Class Libraries)와 자바 클래스 로더(Java Class Loader)가 포함됩니다. - JVM ( Java Virtual Machine )
Java를 실제로 실행시키는 도구이다. 자바 어플리케이션을 클래스 로더를 통해 읽어 들여 자바 API와 함께 실행한다. 그리고 가장 중요한 메모리관리, GC을 수행한다. 스택 기반의 가상머신
JRE는 사용자를위한 것이며 JDK는 프로그래머를위한 것입니다. 자바 소스 코드는 컴파일러(Javac)를 사용하여 바이트 코드(.class 파일)라는 중간 상태로 컴파일 됩니다. 컴파일러는 JDK에 내장되어 있습니다. 그 바이트 코드 파일을 JVM의 클래스 로더를 통해 읽어 실행시킵니다.
JVM Architecture
JVM은 클래스 로더 서브 시스템, 런타임 데이터 영역, 실행 엔진로 구성되어있다.
클래스 로더 서브 시스템
클래스 로더는 JVM안에 존재하며, 클래스를 메모리에 로드해서 실행할 수 있게 해줍니다. 자바 프로그램은 한 개 혹은 그 이상의 클래스들의 조합으로 실행됩니다. 그리고 실행 시 모든 클래스 파일들이 한 번에 JVM 메모리에 로딩되지 않고 요청되는 순간 로딩됩니다. 이것은 자바의 동적 클래스 로딩이라하고 자바의 클래스 로더가 이런 역할을 수행합니다. 클래스 로더란 '.class' 바이트 코드를 읽어 들여 클래스 객체를 생성하는 역할을 담당합니다. 즉, 클래스 로더는 클래스가 요청될 때 파일로부터 읽어 메모리로 로딩하는 역할을 하며 자바 가상 머신의 중요한 요소 중 하나입니다.
클래스 로더가 환경 변수에 등록된 디렉터리에 있는 모든 클래스들을 먼저 JVM에 로딩합니다. JVM에 로딩된 클래스만이 JVM에서 객체로 사용할 수 있습니다. 클래스 로딩은 클래스를 로딩하는 시점 또는 실행 중간에도 할 수 있습니다. 런타임에서 클래스를 처음 참조 할 때 Loading( 적재 ), Linking( 연결 ), Initialization( 초기화 )를 실행하게 됩니다.
1. Loading ( 적재 )
클래스 파일을 바이트 코드로 읽어 메모리로 가져오는 과정으로 3가지 유형의 클래스 로더가 있으며 4가지 주요 원칙을 따릅니다.
- VIsibility ( 가시성 원리 )
자식 클래스 로더는 부모 클래스 로더가 로드 한 클래스를 볼 수 있지만, 부모 클래스 로더는 자식 클래스 로더가 로드 한 클래스를 찾을 수 없음을 나타냅니다. - Uniqueness (고유성 원칙 )
부모에 의해 로드 된 클래스는 자식 클래스 로더에 의해 다시 로드되지 않아야하며 중복 클래스 로드가 발생하지 않도록합니다. 클래스명이 같아도 패키지가 다르면 구분이 가능하다. - Delegation Hierarchy ( 위임 계층 원칙 )
위의 2 가지 원칙을 만족시키기 위해 JVM은 위임 계층 구조에 따라 각 클래스 로딩 요청에 대한 클래스 로더를 선택합니다. 여기서 가장 낮은 하위 레벨에서 시작하여 Application Class Loader는 수신 된 클래스로드 요청을 확장 클래스 로더에 위임 한 다음 확장 클래스 로더가 요청을 부트 스트랩 클래스 로더에 위임합니다. 요청한 클래스가 부트 스트랩 경로에 있으면 클래스가 로드됩니다. 그렇지 않으면 요청이 다시 확장 클래스 로더 레벨로 다시 전송되어 확장 경로 또는 사용자 정의 경로에서 클래스를 찾습니다. 또한 실패하면 요청이 시스템 클래스 경로에서 클래스를 찾기 위해 Application Class Loader로 돌아와 Application Class Loader가 요청 된 클래스를로드하지 못하면 런타임 예외가 발생 java.lang.ClassNotFoundException합니다. - No Unloading ( 언로딩 없음 )
클래스 로더는 클래스를 로드 할 수 있지만, 로드 된 클래스를 언로드 할 수 없습니다. 언로드하는 대신 현재 클래스 로더를 삭제하고 새 클래스 로더를 작성할 수 있습니다.
- 부트스트랩 클래스 로더(Bootstrap Class Loader)
$JAVA_HOME/jre/lib/rt.jar에서 rt.jar에 있는 JVM을 실행시키기 위한 핵심 클래스들을 로딩합니다. - 확장 클래스 로더(Extenstion Class Loader)
$JAVA_HOME/jre/lib/ext 경로에 위치해 있는 자바의 확장 클래스들을 로딩하는 역할을 합니다. - 시스템/애플리케이션 클래스 로더(System/Application Class Loader)
$CLASSPATH에 설정된 경로를 탐색하여 그곳에 있는 클래스들을 로딩하는 역할을 합니다.
직접 코딩한 .class 확장자 파일을 로딩합니다.
2. Linking ( 연결 )
로드된 클래스나 인터페이스를 확인하고 준비하는 과정입니다. 가장 복잡한 과정으로, 읽어온 바이트 코드가 자바 규칙을 따르는지 검증하고, 클래스에 정의된 필드, 메소드, 인터페이스들을 나타내는 데이터 구조를 준비하며, 그 클래스가 참조하는 다른 클래스를 로딩합니다.
Linking ( 연결 )은 아래와 같이 3단계로 이루어진다.
- Verification ( 검증 )
.class 파일의 정확성을 확인한다(Java 언어 사양에 따라 코드가 올바르게 작성되었는가? JVM 사양에 따라 유효한 컴파일러에 의해 생성되는가?) 가장 복잡한 과정이며, 가장 오랜 시간이 걸립니다. 연결로 인해 클래스 로딩 프로세스가 느려지더라도 바이트 코드를 실행할 때 이러한 검사를 여러 번 수행할 필요가 없으므로 전체적인 실행이 효율적이고 효과적입니다. 검증이 실패하면 런타임 오류(java.lang)를 발생시킵니다. - Preparation ( 준비 )
JVM은 메모리를 기본 값으로 초기화 한 후, 클래스 변수들을 위한 메모리에 할당합니다. - Resolution ( 실행 )
형식에서 Symbolic Reference를 Direct Reference로 대체합니다.
참조된 실체를 찾기 위해 방법 영역을 검색하여 수행합니다.
3. Initialization ( 초기화 )
클래스나 인터페이스의 초기화 로직을 실행한다.
'Language > Java' 카테고리의 다른 글
[Java] 제네릭 (Generic) (0) | 2021.04.21 |
---|---|
[Java] 다형성 (0) | 2021.01.01 |
[Java] 실행 데이터 영역 (Runtime Data Area) (0) | 2020.12.27 |
[Java] 자바 클래스 로더 (0) | 2020.12.26 |
[Java] 자바란? ( Java ) (0) | 2020.12.25 |
댓글