[IT]/JAVA

[Java] Java Virtual Machine(자바 가상 머신) 이란 / 자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기

ee2ee2 2020. 11. 23. 22:01
728x90
반응형

목표

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

학습할 것

  • JVM이란 무엇인가
  • 컴파일 하는 방법
  • 실행하는 방법
  • 바이트코드란 무엇인가
  • JIT 컴파일러란 무엇이며 어떻게 동작하는지
  • JVM 구성 요소
  • JDK와 JRE의 차이

  • JVM이란 무엇인가

Java Virtual Machine(자바 가상 머신)으로 Java ByteCode(.class)를 OS에 맞게 해석해주는 역할.

Java와 OS 사이에서 중개자 역할을 수행하며, Java가 OS에 독립적으로 실행 및 재사용이 가능하게 한다.

 

특징

- OS에 상관없이 어느 운영체제에서 동작이 가능하도록 함

- Stack 기반의 가상 머신

- 메모리 관리, Garbage Collection을 수행

 

JVM은 Java와 OS의 중개자 역할을 한다.


  • 컴파일 하는 방법

컴파일(complie) 이란?

 : Java파일을 자바 컴파일러(javac.exe)를 이용하여 JVM이 이해할 수 있는 ByteCode로 변환하는 것.

이 후, 실행 시 JVM이 ByteCode를 컴퓨터가 이해 가능한 기계어로 바꿔주는 역할을 한다.

(.java -> .class 파일로 변환하는 작업)

 

1) cmd 창 이용하기

    명령어 : class 파일 위치로 이동 후, javac 클래스명.java -> class 파일 생성 완료

2) JAVA IDE (Integrated Development Environment) 사용하기

: Eclipse, IntelliJ


  • 실행하는 방법

: 컴파일된 코드를 자바 인터프리터(java.exe)를 활용하여 해당 .class의 위치에서 java class파일명 명령어로 실행

실행 결과

더보기

1) 클래스 로더 (Class Loader)

: 실행에 필요한 .class 파일을 Loading

 

2) 바이트코드 검증 (ByteCode Verifier)

: 해당 파일의 코드가 올바른지 검증. 정해진 규칙에 따라 작성되어있는지 확인하는 과정

 

3) 기계어 코드로 변환

: 컴퓨터에서는 기계어 코드만 실행가능. ByteCode 상태의 파일을 컴퓨터가 이해할 수 있도록 자바 인터프리터(java.exe) 및 JIT 컴파일러를 통해 변환(해석)


  • 바이트코드란 무엇인가

 : JVM이 이해할 수 있는 언어로 변환된 자바소스코드.

  자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1Byte라서 bytecode라 불림.

   Java ByteCode는 JVM만 설치되어있으면, 어느 운영 체제에서라도 실행 가능


  • JIT 컴파일러란 무엇이며 어떻게 동작하는지

- JIT(just-in-time compilation) 컴파일러란?

: 프로그램을 실제 실행하는 시점에 ByteCode를 기계어로 번역하는 컴파일

[동적 번역(Dynamic Translation)이라고도 함.]

 

- JIT(just-in-time compilation) 동작 방식?

실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 해당 코드를 캐싱하여, 

같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지 -> 빠름

 

JVM 실행엔진 내 포함되어 있음!

 

 

* JIT 컴파일 vs 정적 컴파일 

- JIT 컴파일 : 프로그래밍 언어를 읽어가면서 해당 기능에 대응하는 기계어 코드를 실행

- 정적 컴파일 : 실행하기 전에 프로그램 코드를 기계어로 번역


  • JVM 구성 요소

더보기

 1. Class Loader

   -  자바 프로그램을 실행하면 .java 파일을 컴파일러를 통해 .class(자바 바이트코드) 파일로 변환된다.

      Class Loader는 해당 파일을 실행(Runtime)하는 시점에 Runtime Data Area에 Loading.

 

      즉, 컴파일 하는 시점이 아닌 클래스를 처음으로 참조하는 시점(Class의 Instance를 만들 때)

Class Loader를 통해 메모리(Runtime Data Area)에 로드.


2. Execution Engine

  - Class Loader를 통해 JVM 내의 Runtime Date Area에 배치된 Bytecode를 실행  

     Execution Engine은 자바 바이트코드를 명령어 단위로 읽어서 실행.

 

  - Execution Engine은 바이트 코드를 실제로 JVM 내부에서 기계어 형태로 변경하며, 2가지 방식이 있음

  • Interpreter
  • JIT(Just-In-Time) Compiler

3. Runtime Data Area

   - JVM이 운영체제 위에서 실행될 때 할당받는 메모리 영역

 

Metod Area

클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보같은 필드 정보

메소드의 이름, 리턴 타입, 파라미터, 접근 제어가 정보 같은 메소드 정보,

Type 정보(Interface / Class), Constant Pool(상수 풀 : 문자 상수, 타입, 필드, 객체 참조가 저장), static 변수,

final class 변수 등이 생성되는 영역

 

Heap Area

new 키워드로 생성된 객체와 배열이 생성되는 영역.

메소드 영역에 로드된 클래스만 생성 가능하고,

GC(Garbage Collector)가 참조되지 않은 메모리를 확인하고, 제거하는 영역

 

Stack Area

지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값 등이 생성되는 영역.

ex)  Person p = new Person(); 

Person p는 Stack 영역 / new 로 생성된 Person Class의 인스턴스는 Heap 영역

-> 스택영역에 생성된 p의 값으로 Heap영역의 주소값을 가짐.

즉, 스택 영역에 생성된 p가 힙 영역에 생성된 객체를 가리키고(참조하고) 있는 것

 

PC Area

Program Counter. Thread가 생성될 때마다 생성되는 영역.

현재 Thread가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이며,

이를 이용하여 Thread를 번갈아가며 수행가능

 

Native Method Stack

자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역.

 

 

여러 Thread가 생성되었을 때,

Method 영역과 Heap영역은 모든 Thread가 공유.

Stack 영역, PC 영역, Native Methos Stack은 각각의 Thread마다 생성되고, 공유되지 않음.


4. Garbage Collection

   - 메모리 관리를 위한 방법.

     프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된(사용안하는) 영역(Heap)을 해제하는 기능

 


  • JDK와 JRE의 차이

- JDK (Java Development Kit)

: JRE + 개발을 위해 필요한 도구(Javac, java 등)를 포함.   [JDK == JRE + @]

 

 

- JRE (Java Runtime Enviroment)

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

 

JVM이 자바 프로그램을 동작시킬 때, 필요한 JVM, 라이브러리 및 기타 파일들을 포함.

(단, 프로그래밍 도구는 포함되어있지 않아 자바 프로그래밍을 하기 위해선 JDK가 필요)