백기선 자바 스터디 1주차

김성훈·2022년 6월 18일
0
post-thumbnail

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


학습할 것

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


1. JVM이란 무엇인가

JAVA Virtual Machine 자바 가상 머신의 약자를 따서 줄여 부르는 용어.

(여기서 말하는 가상머신은 프로그램을 실행하기 위해서 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것)

JVM은 자바 애플리케이션을 클래스 로더를 통해서 읽으며 자바 API와 함께 실행한다.

JVM은 자바와 OS사이에서 중개자 역할을 수행하며 JAVA가 OS에 구애 받지 않고 재 사용을 가능하게 해줌.

가장 중요한 역할로 메모리 관리, 가비지 컬렉션을 수행한다.


2. 컴파일 하는 방법 / 실행하는 방법

자바가 동작하는 흐름

Java에서 컴파일은 기존의 컴파일 과정과는 조금 다르게 진행된다. 컴파일 언어의 컴파일러들은 코드를 기계어로 변환시키는데 반해 Java의 컴파일러인 javac.exe는 JVM이 이해할 수 있게 중간 단계의 언어인 바이트 코드로 변환시켜 줘서 프로그램을 실행하게되면 JVM이 이 바이트 코드를 기계어로 변환시켜 실행하게 된다

java *.class 명령어를 사용하여 실행 or IDE에서 jdk를 등록후 실행하면 class확장자의 바이트코드를 JVM이 읽어서 실행하게 된다.

  1. Compile : java 확장자가 붙은 소스코드를 class 확장자가 붙은 실행파일로 변환
  2. Run : class 확장자가 붙은 파일을 'java' 로 실행
  3. Input : 실행할 때 , 입력값에 따라서 다르게 동작하여 출력값 만들기
// Program.java

public class Test{

	public static void main(String[] args) {
		System.out.println("Hello Java");
      
	}

}

  1. 저 코드가 있는 자바 파일을 만들고 경로로 이동
  2. javac 명령어를 이용하여 컴파일 과정을 진행한다
  1. 위 과정을 끝내면 class 파일이 생성되어 있고

  2. 실행하면 Hello Java 가 실행된다.


3. 바이트 코드란 무엇인가

자바 바이트 코드 (Java Bytecode) 는 자바 가상 머신이 이해할 수 있는 언어로 변환된 자바 소스 코드를 의미한다.

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

자바 바이트 코드의 확장자는 .class 이며 자바 바이트 코드는 자바 가상 머신만 설치되어 있으면, 어떤 운영체제에서라도 실행 될 수 있다.


4. JIT 컴파일러란 무엇이며 어떻게 동작할까

JIT 컴파일러(Just-In-Time Compiler) 는 인터프리터의 단점을 보완하기 위해 도입된 방식으로 바이트 코드 전체를 컴파일 하여 네이티브 코드로 변경하고 이후에는 해당 메서드를 더 이상 인터프리팅 하지 않고 네이티브 코드로 직접 실행하는 방식이다.

하나씩 인터프리팅 하여 실행하는 것이 아니라 바이트 코드 전체가 컴파일된 네이티브 코드를 실행하는 것이기 때문에 전체적인 실행 속도는 인터프리팅 방식보다 빠름.

네이티브 코드는 캐시에 보관하고 한 번 컴파일된 코드는 캐시에서 바로 꺼내어 실행하기 때문에 빠르게 수행된다.

하지만 JIT 컴파일러가 컴파일하는 과정은 바이트 코드를 하나씩 인터프리팅 하는 것보다 훨씬 오래 걸리기 때문에 JIT 컴파일러를 사용하는 JVM은 내부적으로 해당 메서드가 얼마나 자주 호출되고 실행되는지 체크하고, 일정 기준을 넘었을 때에만 JIT 컴파일러를 통해 컴파일하여 네이티브 코드를 생성한다.

JIT 컴파일러를 통한 컴파일 과정은 바이트 코드를 바로 네이티브 코드로 만든 것이 아니라 안에서 IR(Intermediate Representation)로 변환하여 최적화를 수행하고 그 다음에 네이티브 코드로 변환하는 과정을 거친다


5. JVM 구성 요소

JVM의 구성요소는 Memory 관리, Class Loader, Execution Engine으로 구성되어 있다.

  1. 자바 소스코드(.java) 를 작성한다.
  2. 자바 컴파일러(javac) 가 자바 소스파일을 자바 바이트 코드(.class) 파일로 컴파일 한다.

이때 나오는 자바 바이트 코드는 JVM만 이해할 수 있는 코드이다.

  1. 컴파일된 바이트 코드를 JVM 클래스로더(Class Loader) 에게 전달한다.

  2. 클래스 로더는 동적로딩(Dynamic Loading) 을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(Runtime Data Area), 즉 JVM 메모리에 올린다.

런타임 데이터 영역

프로그램을 수행하기 위해 OS로 부터 별도로 할당받은 메모리 공간

클래스 로더 동작

a. 로드 : 클래스 파일을 가져와서 JVM의 메모리에 로드한다.
b. 검증 : 자바 언어 명세(Java Language Specification) 및 JVM 명세에 명시된 대로 구성되어 있는지 검사한다.
c. 준비 : 클래스가 필요로 하는 메모리를 할당(필드, 메서드, 인터페이스 등등)
d. 분석 : 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경한다.
e. 초기화 : 클래스 변수들은 적절한 값으로 초기화한다.(static 필드)

  1. 실행엔진(Execution Engine) 은 JVM 메모리에 올라온 바이트 코들를 명령어 단위로 하나씩 가져와서 실행한다, 이때 실행 엔진은 두가지 방식으로 변경한다.
  • 인터프리터(Interpreter)
  • JIT(Just In Time) 컴파일러

인터프리터

자바의 특징에 대한 대표적인 표현 중에서 Write Once Run Anywhere 이라는 문구가 있음.

자바가 플랫폼에 독립적이고, 이식성이 높은 언어인 이유는 인터프리터 덕분이다.

각 플랫폼에 맞는 인터프리터가 바이트 코드를 실행하기 때문에 Windows, Linux, Mac 어디서든 실행 가능.

인터프리터는 바이트 코드를 읽고(read), 운영체제가 실행할 수 있도록 기계어로 변경하는 역할을 수행.

JITL:

인터프리터의 속도 문제를 해결하기 위해 만들어진 기능.

자주 실행되는 바이트 코드 영역을 런타임 중에 기계어로 컴파일 하여 사용함.

Class loader로 바이트 코드를 불러와서 Runtime Data Areas에 배치하여 Execution Engine으로 실행하게 되는 것


6. JDK와 JRE의 차이

JRE(Java Rentime Environment)는 Java 애플리케이션을 생성하고 실행하기 위한 일련의 구성요소이다.
JDK(Java Development Kit) 는 JRE + 개발에 필요한 것들을 가지고 있는 더 큰 범위라고 보면된다.
즉, JDK는 Java 프로그램 개발과 실행을 할 수 있는 환경을 제공하며, JRE는 Java프로그램을 실행하는 환경을 제공한다.


출처

[JAVA] JVM의 구성요소 및 동작원리

자바가상머신이란

JVM - 실행 엔진(Execution Engine)

profile
"한 명이 걷는 천 걸음 보다 천 명이 함께 걷는 한 걸음이 성공의 시작이고 완성이다"

0개의 댓글