JVM (실행 관점)

진주원(JooWon Jin)·2024년 5월 12일
0

Java

목록 보기
3/3
post-thumbnail

JVM (실행 관점)

JVM

Java Virtual Machine (자바 가상 머신)

  • 자바 기반 애플리케이션실행 환경 제공

흐름의 이해

사용자 언어로 작성된 프로그램이 실행되기 위한 흐름에 대한 이해가 필요하다

  • 결국 사용자가 작성한 프로그램이 실행되기 위해서는 OS와의 통신이 필요하다.
  • 기계어로 변환된 코드가 사용자 영역에서 커널 영역 사이의 시스템 콜 기반으로 통신이 되어야 한다.

여기서 중요한 점은 OS의 종류가 다르다면(Window , Mac) 제공하는 시스템 콜의 종류도 다르고 결국 언어마다 OS에 대한 종속성이 존재할 수 있다.

Java의 특징

Java 언어의 가장 큰 특징은 ‘OS에 종속적이지 않다’ 라는 것이다. 이것이 가능한 이유는 Java 언어가 실행되는 환경인 JVM 때문인 것이다.

  • JVM은 자체적인 Java 언어의 실행 환경을 제공하고 JVM이 OS의 커널 영역과 통신한다. 이러한 이유 때문에 JVM만 설치되어 있다면 OS에 상관없이 Java 언어를 실행시킬 수 있다.

JVM은 OS에 종속적이다

Java 언어는 OS에 종속적이지 않는 실행이 가능하다. 하지만 결국 OS단과 통신하는 중간 매개체로서 JVM이 존재한다. 결국 JVM은 OS에 종속적이라는 것이다.

image

  • 위의 이미지를 보면 알 수 있듯 각 OS 별로 별도의 JVM을 제공한다.

Java 실행 과정

image

*.java

Java 언어로 작성된 코드 ( 우리가 흔히 자바 소스 코드라 부르는 파일이다.)

  • 모든 언어로 작성된 코드가 그렇듯 CPU가 이해하기 위해서는 기계어로 변환되어야 한다.
  • 하지만 JVM이 OS와의 통신을 담당하기 때문에 결국 자바 소스 코드는 JVM이 이해하기 위한 형태로 변환되어야 한다.

Java Compiler ( javac )

  • *.java 소스 코드는 *.class 파일로 변환시켜 준다. ( JVM이 인식할 수 있는 형태로 변환한다 )
  • .class 파일은 Java 바이트 코드라고 한다.

Class Loader

런타임 시 처음으로 클래스를 참조할 때 해당 클래스를 로드하고 JVM 메모리 영역에 배치

  • Runtime 시 클래스의 동적 로드를 담당
  • 클래스의 인스턴스화를 수행하는 곳

Execution Engine (실행 엔진)

JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 실행하는 역할

  • 명령어를 실행하는 방식에는 인터프리터 방식과 JIT 컴파일러 방식이 있다.

인터프리터

바이트 코드 명령어를 하나씩 읽어서 해석하고 실행합니다. 하나하나의 실행은 빠르나, 전체적인 실행 속도가 느리다는 단점을 가집니다.

JIT 컴파일러

  • 인터프리터의 느린 속도의 단점을 보완하기 위해 도입된 방식

바이트 코드 전체를 컴파일하여 바이너리 코드로 변경하고 이후에는 해당 메서드를 더이상 인터프리팅 하지 않고, 바이너리 코드로 직접 실행하는 방식

JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 역시 변환하는데 비용이 발생

Deep In Class Loader

동적 로딩

Java언어의 특징으로 ‘동적 로딩을 지원한다’가 있는데 이는 Class Loader를 통해 가능한 것이다.

  • 동적 로딩
    • 실행 시 모든 클래스가 로딩되지 않고 필요한 시점에 클래스를 로딩하여 사용
    • JVM의 Method 영역에 클래스를 동적으로 Load 하는 것

클래스 로더 시스템

클래스 로더에서 Java class 파일의 정보를 Method 영역으로 Load하는데 있어 3가지 단계를 거치게 된다. (로딩 → 링크 → 초기화)

image

Loading

.class 파일을 Binary Code로 변환하여 Method 영역에 저장

  • 로딩 후에 해당 클래스 타입의 객체를 생성하여 Heap Area에 저장
  • Method 영역에 저장되는 정보
    • 클래스 파일과 Class, Interface, Enum의 관련 여부
    • 변수나 메서드 정보

Linking

코드 내부의 레퍼런스를 연결

  • Verify
    • .clsss 파일 형식의 유효성 검사
  • Prepare
    • 클래스가 필요한 메모리 할당 + 데이터 구조 준비
  • Resolve
    • 심볼릭 메모리 레퍼런스를 메서드 영역에 있는 실제 레퍼런스로 변환

참조 관계의 클래스에 대해 메모리 주소를 기반으로 참조 관계를 구성하는 것이 아닌 참조하는 클래스의 이름으로 레퍼런스 관계가 지정되어 있다.

Initalization

Static 변수를 초기화하고 값을 할당하는 과정

클래스 로더 종류

Delegation Model (위임 모델)

class 로딩 과정에 있어 자신의 부모 class loader에게 로딩을 위임하는 방식

image

  • Class Loader는 크게 Bootstrap - Extension - System 3가지가 있다.

Bootstrap

자바의 기본 라이브러리 및 자바 가상 머신 자체를 포함

Extension

표준 확장 폴더에서 클래스를 로드

System

사용자가 정의한 클래스 및 외부 라이브러리들이 위치한 곳

동작 과정

  1. JVM의 메소드 영역에 클래스가 로드되어 있는지 확인한다. 만일 로드되어 있는 경우 해당 클래스를 사용한다.
  2. 메소드 영역에 클래스가 로드되어 있지 않을 경우, 시스템 클래스 로더에 클래스 로드를 요청한다.
    • 시스템 클래스 로더확장 클래스 로더에 요청을 위임한다.
    • 확장 클래스 로더는 부트스트랩 클래스 로더에 요청을 위임한다.
  3. 부트스트랩 클래스 로더는 부트스트랩 Classpath(JDK/JRE/LIB)에 해당 클래스가 있는지 확인한다. 클래스가 존재하지 않는 경우 확장 클래스 로더에게 요청을 넘긴다.
  4. 확장 클래스 로더는 확장 Classpath(JDK/JRE/LIB/EXT)에 해당 클래스가 있는지 확인한다. 클래스가 존재하지 않을 경우 시스템 클래스 로더에게 요청을 넘긴다.
  5. 시스템 클래스 로더는 시스템 Classpath에 해당 클래스가 있는지 확인한다
    • 클래스가 존재하지 않는 경우 ClassNotFoundException을 발생시킨다.

클래스 로더 3원칙

  • 위임 원칙
    • 클래스를 찾기 위한 요청을 받았을 때 상위 모델에게 요청을 위임한다.
  • 가시 범위 원칙
    • 하위 클래스 로더는 상위 클래스 로더가 로드한 클래스를 볼 수 있지만, 반대로 상위 클래스 로더는 하위 클래스 로더가 로드한 클래스를 알 수 없다.
  • 유일성 원칙
    • 하위 클래스 로더가 상위 클래스 로더에게 로드한 클래스를 다시 로드하지 않아야 한다는 원칙

[Java] JVM의 클래스 로더란?

동적 로딩

로드 타임 동적 로딩

하나의 클래스를 로딩하는 과정에서 동적으로 다른 클래스 파일을 로드하는 것

런타임 동적 로딩

코드를 실행하는 순간 클래스를 로딩하는 것 ( Class.forName() )

profile
Young , Wild , Free

0개의 댓글