[ Java 기초 ] JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가

황승환·2021년 12월 21일
0

Java 기초

목록 보기
1/6
post-thumbnail

Goal

자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기

Study

JVM이란 무엇인가

JVM이란 JAVA Virtual Machine의 약자로, 자바 가상 머신을 뜻한다. 여기서 가상 머신이란 프로그램의 구동을 위해 필요한 물리적 머신을 소프트웨어로 구현한 것이다. ARM 아키텍쳐 같은 하드웨어는 레지스터 기반으로 동작하는 반면, JVM은 스택 기반으로 동작하는 가상머신이다.

역할

  • 자바 애플리케이션을 클래스 로더를 통해 읽어 들여 자바 API와 함께 실행한다.
  • JAVA와 OS 사이에서 중개자 역할을 수행하여 JAVA가 OS의 구애를 받지 않고 재사용하게 한다.
  • 메모리 관리(Garbage collection)를 수행한다.

JVM의 구성

Class Loader

  • Runtime 시점에서 .class파일의 바이트코드를 읽고 메모리에 저장
  • 로딩(Loading): 클래스를 읽어오는 과정
  • 링크(Link): 레퍼런스를 연결하는 과정
  • 초기화: 정적(static)값들을 초기화 and 변수에 할당

Runtime Data Areas

  • JVM이 프로그램을 수행하기 위해 OS로부터 별도로 할당받는 메모리 공간
  • Method Area, Heap, Java Threads, Program Counter Registers, Native Internal Threads로 구성
    -> Method Area: 모든 쓰레드가 공유하는 메모리 영역으로 클래스, 인터페이스, 메소드, 필드, Static 변수 등의 바이트 코드 등을 보관
    -> Heap: 런타임시 동적으로 할당하여 사용하는 영역으로 Class를 통해 instance를 생성하면 Heap에 저장됨
    -> Program Counter Registers: CPU가 Instruction을 수행하는 동안 필요한 정보를 저장
    -> Native Method Stack: Java 이외의 언어로 작성된 native코드를 위한 Stack
    -> JVM Stack: 쓰레드가 시작될 때에 생성되며 Method와 Method의 정보를 저장

Execution Engine

  • JIT Compiler, Garbage Collector로 구성
  • Load된 Class의 바이트코드를 실행하는 Runtime module
  • Class Loader를 통해 JVM 내의 Runtime Data Areas에 배치된 바이트 코드는 Execution Engine에 의해 실행

Class Loader

Class Loader는 크게 로딩->링크->초기화 순으로 진행된다.

Loading

  • 클래스 로더가 .class 파일을 읽는다.
  • .class 파일의 내용에 따른 적절한 바이너리 데이터를 만든다.
  • Method Area에 저장한다.
  • Loading이 끝나면 해당 Class Type의 Class 객체를 생성하여 Heap에 저장한다.
Loading 순서

Bootstrap, Extension, Application 3가지의 Class Loader가 존재한다. Bootstrap -> Extension -> Application 순서로 탐색을 진행한다. 일반적으로는 Application에 대부분 존재한다. 3가지의 Class Loader에서 원하는 Class를 찾지 못하면 ClassNotFoundException을 발생시킨다.

Link는 Verify -> Prepare -> Resolve 3가지 단계로 이뤄진다.

  • Verify
    ->바이트 코드를 수정했을 수 있기 때문에 .class 파일 형식이 유효한지 확인한다.
  • Prepare
    -> 클래스 변수(static 변수)와 기본값에 필요한 메모리를 준비하는 과정이다.
  • Resolve
    -> 사용하는 환경에 따라 동작 유무가 정해진다. 즉, Optional하다.
    -> 심볼릭 메모리 레퍼런스를 Method Area에 있는 실제 레퍼런스로 교체한다.

Initialization

Link의 Prepare 단계에서 확보한 메모리 영역에 클래스의 static값들을 할당한다.

JVM 개념이 중요한 이유

한정된 메모리를 효율적으로 사용하여 최고의 성능을 내기 위해 JVM의 개념을 알고 있는 것이 필요하다. 동일한 기능을 수행하는 프로그램이라도 메모리 관리에 따라 성능이 달라진다. 그만큼 메모리 관리가 중요하기 때문에 메모리 구조를 잘 알고 있는 것이 중요하다.

Java 코드의 실행 과정

컴파일 단계

  • 소스코드(.java)가 자바 컴파일러에 의해 JVM을 위한 중간 단계의 코드인 자바 바이트 코드(.class)로 컴파일된다.

런타임 단계

  • Class Loader는 동적 로딩을 통해 컴파일된 클래스들을 JVM 내로 로드하고 적재한다. 이때 클래스들은 바이트코드로 존재한다.
  • 적재된 클래스들은 JVM의 메모리 역할을 하는 Runtime Data Area로 올라간다.
  • Execution Engine은 바이트 코드를 기계어로 바꿔주는데, 이 때 인터프리터, JIT 컴파일러 이렇게 두가지 방식이 존재한다.

Java Complier

자바 컴파일러는 자바를 가지고 작성한 자바 소스 코드를 JVM이 이해할 수 있는 자바 바이트 코드로 변환하는 역할을 한다. 이는 결국 .java파일을 .class파일로 변환하는 것이다.

.java 파일 실행 실습

실습이라 하기엔 너무나 간단하지만 진행해보았다.
1. hello world를 출력하는 Hello.java를 작성하고 저장한다.
2. javac 명령어를 사용하여 Hello.java를 컴파일한다.

$ javac Hello.java
$ ls
Hello.java
Hello.class
  1. java 명령어를 사용하여 Hello.class 파일을 실행한다.
$ java Hello.class
hello world

Java Bytecode

자바 바이트코드란 JVM이 이해할 수 있는 언어로 변환된 자바 소스 코드를 의미한다. 자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1byte라서 자바 바이트 코드라고 불리고 있다. 확장자는 .class를 사용하고 JVM만 설치되어 있으면 어떤 OS에서도 실행 가능하다.

JIT Complier

Java 코드의 실행 과정에서 런타임 단계에 잠깐 등장한 JIT Compiler에 대해 간단하게 알아보았다. JIT Compiler를 설명하기 위해 인터프리터와 컴파일러의 방식을 비교해보았다.

인터프리터

  • 소스코드를 한 문장씩 읽고 바로 기계어로 변환
  • 개발 편의성은 높지만 실행 속도가 느리다.

컴파일러

  • 전체 소스코드를 읽어 기계어로 변환하고 그 후에 변환된 코드 실행
  • 개발 편의성은 떨어지지만 실행 속도가 빠르다.

JIT Complier

JIT Compiler는 인터프리터의 느린 속도를 보완하기 위해 등장하였다. 간단하게는 인터프리터와 컴파일러를 결합한 형태라고 할 수 있다.

  • 인터프리터 방식을 사용하다가 적정한 때에 바이트코드 전체를 기계어로 바꾼다.
  • 인터프리터 방식으로 바이트코드를 기계어로 변환할 때에 중복으로 변환되는 코드들은 캐싱 기법을 통해 바로 변환하여 속도를 향상시킨다.

JRE vs JDK

JRE(Java Runtime Environment)

컴파일된 자바 프로그램을 실행시킬 수 있는 자바 환경

  • JRE는 JVM이 자바 프로그램을 동작시킬 때 필요한 라이브러리 파일들과 기타 파일들을 가지고 있다.
  • JRE는 JVM의 실행 환경을 구현했다고 할 수 있다.
  • 자바 프로그램을 실행시키기 위해선 JRE를 반드시 설치해야한다.
  • 자바 프로그래밍 도구는 포함되어 있지 않기 때문에 자바 프로그래밍을 위해서는 JDK가 필요하다.

JDK(Java Development Kit)

자바 프로그래밍시 필요한 컴파일러 등을 포함

  • JDK는 개발을 위해 필요한 도구(javac, java 등)들을 포함한다.
  • JDK를 설치하면 JRE도 같이 설치된다.
  • JDK = JRE + @ 라고 할 수 있다.
profile
꾸준함을 꿈꾸는 SW 전공 학부생의 개발 일기

0개의 댓글