[JAVA] 알아보자, JVM (Java Virtual Machine)!

이인수·2023년 9월 11일
0

Java

목록 보기
1/2
post-thumbnail

Java Virtual Machine (이하 JVM)은 '자바를 실행하기 위한 가상 기계' 정도로 직역할 수 있다.

JVM / JRE / JDK

JVM (Java Virtual Machine)

  • 클래스 파일(.class) 안에 들어있는 자바 바이트코드를 인터프리터나 JIT컴파일러를 실행해 OS에 특화된 코드로 변환하여 실행하는 프로그램
  • JVM은 OS에 종속적이지만, Java는 OS에 종속적이지 않습니다. 따라서 Java의 중요한 철학인 WORA를 가능하게 합니다.
  • 바이트 코드의 실행 방법에 대한 스펙이기 때문에 다양한 구현체가 있습니다.

JRE (Java Runtime Environment)

  • JVM과 런타임에 사용되는 라이브러리, 프로퍼티 세팅과 리소스 파일 등을 포함하는 패키지
  • Java 프로그램을 실행시키기 위해 필요

JDK (Java Development Kit)

  • JRE와 개발 시 필요한 다양한 개발 도구 포함하는 SDK
  • Java 프로그램을 직접 개발하기 위해 필요
  • vendor: Oracle, Amazon, Azul, BellSoft ...

JVM 구성요소

Runtime Data Area

  • 모든 스레드들이 공유하는 영역
    • Heap, Method
    • JVM의 생명주기에 따라 생성 및 삭제
  • 스레드 별 할당되는 영역
    • PC Register, Stack, Navtive Method Stack
    • 각 스레드의 생명주기에 따라 생성 및 삭제

Heap

  • 클래스의 인스터스(객체)들과 배열들이 저장되는 공간
  • Garbage Collection에 의해 관리됨

Method (=Class =Static)

Runtime Constant Pool

  • 클래스 마다 하나의 Constant Pool 존재 -> 클래스가 생성되어 Heap에 할당될 때 만들어지며 클래스가 삭제되면 삭제
  • Constant Pool의 Entry는 배열과 같이 인덱스 번호를 통해 접근
  • Type, Field, Method, Literal Constant로의 모든 심볼릭 링크 존재

Type Infomation

  • 전체 이름 (패키지명 + 클래스명)
  • 직계 부모, 자식 클래스 전체 이름
  • 클래스, 인터페이스 여부
  • 접근 제어자 (public / abstract / final)

Class Variable

static 키워드로 선언된 변수 의미

  • 모든 인스턴스에 공유 되며 인스턴스가 없어도 직접 접근이 가능
  • 이 변수는 인스턴스가 아닌 클래스에 속함
  • 클래스를 사용 하기 이전에 이 변수들은 미리 메모리를 할당 받음
  • final로 선언 하는 경우 변수가 아닌 상수로 취급 되어 Runtime Constant Pool에 Literal Constant로 저장

Reference to class ClassLoader and class Class

  • Reference to class ClassLoader

    • class가 JVM에 의해 load될 때 어떤 Class Loader에 의해서 load되었는지 정보가 저장
  • Reference to class Class

    • class가 JVM에 의해서 load되면 항상 java.lang.class 클래스의 객체 생성
    • method area에서는 type 정보의 일부로 해당 객체를 참조

Method Information

  • 이름
  • 리턴타입
  • 매개변수 (갯수, 타입)
  • 접근 제어자 (public / private / protected / static / final / syncronized / native / abstract)
  • 구현 부분이 존재 하는 경우 (abstract, native가 아닌 경우)
    • 바이트코드
    • Method의 Stack Frame의 Operand Stack 및 지역 변수 배열
    • Exception Table

Method Table

  • class의 method에 대한 Direct Reference를 갖는 자료구조
  • 부모 클래스의 메소드에 대한 참조도 가짐

Field information

  • 이름
  • 타입
  • 접근 제어자 (public / private / protected / static / final / volatile / transient)

PC Register

  • JVM이 현재 실행중인 명령어의 주소를 저장

Stack

  • Frame이라는 자료구조를 저장
  • C 언어 등 전통적인 언어의 스택 구조와 유사
    • 지역 변수, 함수의 실행 결과를 저장하며 함수 호출과 반환을 담당

Frame

  • 데이터, 반환 값을 저장하는 자료구조
    • 지역 변수 배열, Operand Stack, RunTime Constant Pool에 대한 참조값
  • 함수의 생명주기에 따라 생성 및 삭제
  • 동적 할당은 코드 실행 시점에 심볼릭 링크를 해석해 고정된 주소값으로 변환
  • 심볼릭 링크를 통해 객체 지향 언어의 핵심인 late-binding(dynamic binding) 구현

Native Method Stack

  • 다른 언어로 작성된 코드를 실행할 때 사용되는 스택
  • JVM에 의해 컴파일된 바이트 코드가 아닌 실제 실행 할 수 있는 기계어로 작성된 네이티브 프로그램을 실행
  • Java Native Interface를 통해 바이트 코드로 전환하여 저장
  • 커널이 스택을 선점해 독자적으로 프로그램을 실행

Class Loader

  • 위임 모델
    • 자신에게 클래스 로딩 요청이 들어오면 자신의 부모 클래스 로더에게 클래스 로딩 요청을 보내고 부모 클래스 로더가 클래스를 찾지못하면 그 후에 자신이 클래스를 탐색을 진행
  • 계층 구조
    • 상위 클래스 로더의 클래스는 하위 클래스에서 볼 수 있지만 그 반대는 불가능
    • 이를 통해 클래스 로더의 책임은 분리하고 클래스 로더는 자신이 책임지는 클래스를 로딩

Bootstrap Class Loader

  • 네이티브 코드로 작성되었으며 JVM에 내장
  • JVM이 시작될 때 실행되며 java.lang package 처럼 JVM 실행에 필요한 클래스들을 로딩할 때 사용

Platform Class Loader

  • java.lang.ClassLoader의 인스턴스로 Java SE platform API 등 자바에서 기본적으로 제공해주는 클래스를 로딩할 때 사용
  • Bootstrap Class Loader를 부모로 가짐
  • JAVA 8 이후 Extension Class Loader에서 Platform Class Loader로 명칭 변경

System Class Loader

  • java.lang.ClassLoader의 인스턴스로 유저가 작성한 클래스를 로딩할 때 사용
    • ClassPath에 명시된 경로를 통해 클래스를 탐색
  • Platform Class Loader를 부모로 가짐
  • JAVA 8 이후 Applicaiton Class Loader에서 System Class Loader로 명칭 변경

Execution Engine

Oracle의 Hotspot 기준

  • 코드를 컴파일 하는 방법을 최적화 하기 위해 라인별 adaptive compiler를 사용
  • 라인별로 바이트 코드를 읽어 기계어로 변환해 실행하며 기본적으로는 인터프리터를 통해 실행을 하지만 자주 등장하는 바이트 코드일 경우 JIT 컴파일러를 사용해 컴파일을 하는 방법을 통해 실행 방법을 최적화

인터프리터

  • 바이트코드 명령어를 하나씩 읽어서 해석하고 실행
  • 장점
    • 바이트코드 하나하나의 해석이 빠름
  • 단점
    • 인터프리팅 결과의 실행은 느림
    • 동일한 바이트 코드를 매번 해석하기 때문에 비효율적

JIT(Just-In-Time) 컴파일러

  • 인터프리터의 단점을 보완하기 위해 도입
  • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트코드 전체를 컴파일하여 네이티브 코드로 변경하고, 이후에는 해당 메서드를 더 이상 인터프리팅하지 않고 네이티브 코드로 직접 실행하는 방식
  • 네이티브 코드를 실행하는 것이 하나씩 인터프리팅하는 것보다 빠르고, 네이티브 코드는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 계속 빠르게 수행

출처

profile
삐약🐣

0개의 댓글