무향향수

[JAVA] JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가 본문

JAVA 스터디

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

튼튼한장 2023. 7. 18. 13:14

목차🏈

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

 

 

🏈 JVM이란 무엇인가

  • JVM = Java Virtual Machine = 자바 실행을 위한 가상 기계(컴퓨터)'
  • Java는 OS에 종속적이지 않기 때문에 OS 위에서 Java 를 실행시킬 수 있도록 도와주는 것이 필요하다.
  • 그것이 바로 JVM이다.
  •  JVM이란 OS에 종속받지 않고 CPU 가 Java를 인식하고 실행할 수 있게 해주는 가상 컴퓨터이다.
⭐ 그래서 일반적인 프로그램의 경우 OS에 종속적이지만, JAVA의 경우 JVM이 존재하기 때문에 OS에 종속받지 않고 JAVA 프로그램을 실행시킬 수 있는 것이다.

 


🏈 컴파일 하는 방법

 

  • .java 파일을 .class라는 Java bytecode로 바꾸기 위하여 Java Compiler를 사용해준다.
  • Java Compiler는 JDK를 설치하면 javac.exe라는 실행 파일 형태로 설치된다.
  • JDK 설치 후 bin 폴더를 확인하면 javac.exe 를 확인할 수 있다.
  • Java Complier의 javac명령어를 사용하면 .java파일을 .class 파일로 변환할 수 있다.
⭐ .java -> .class 파일로 변경하기 위해 컴파일러의 javac명령어를 사용한다.

컴파일 과정

  1. Test.java 파일을 생성한 후 cmd창에서 Java파일이 있는 곳으로 이동한다.
  2. 파일이 있는 위치에서 javac Test.java 명령어를 입력하면 컴파일이 진행되어 Test.class 파일이 생성된다.

 


🏈 실행하는 방법

  1. 컴파일 과정에서 생성한 Test.class파일을 java 명령어로 실행시켜준다.
  2. cmd창에서 Test.class파일이 생성된 곳으로 이동한 후 java Test를 입력하면 실행할 수 있다.
  3. 실행결과가 화면에 출력되어 확인할 수 있다.

 


🏈 바이트코드란 무엇인가

  • 바이트코드 : 가상 머신(VM)에서 돌아가는 실행 프로그램을 위한 이진 표현법
  • 자바 바이트 코드(Java bytecode)는 JVM이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미한다.
  • 자바 컴파일러에 의해 변환된 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불리고 있다.
  • 바이트 코드는 다시 실시간 번역기 또는 JIT 컴파일러에 의해 바이너리 코드로 변환된다.

 


바이너리 코드란? 

  • 컴퓨터가 인식할 수 있는 0과 1로 이루어진 이진 코드

 


기계어란?

  • 0과 1로 이루어진 바이너리 코드이다.
  • 기계어가 바이너리 코드로 이루어지긴 했지만 모든 바이너리 코드가 기계어인 것은 아니다.
  • 기계어는 언어가 아니라 CPU가 이해하는 명령어 집합이다.

 

⭐ 바이트 코드 :  가상 머신(VM)에서 돌아가는 실행 프로그램을 위한 이진 표현법
⭐ 바이너리 코드 : 컴퓨터가 인식할 수 있는 이진 코드
⭐ 기계어 : CPU가 이해하는 명령어 집합

 


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

 

  • JIT 컴파일(just-in-time compliation) 또는 동적 번역(dynamic translation) 이라고 한다.
  • JIT 컴파일러는 프로그램 실행 시점에 기계어로 번역하는 컴파일러이다.
  • 인터프리터의 단점을 보완하기 위해 도입되었다.
  • JIT 컴파일러는 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변경하고, 이후에는 더 이상 인터프리팅 하지 않고 기계어로 직접 실행하는 방식이다.
  • 기계어(컴파일된 코드)는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 빠르게 수행하게 된다.
  • JIT 컴파일러가 컴파일하는 과정은 바이트 코드를 인터프리팅하는 것보다 훨씬 오래 걸리기 때문에 한 번만 실행되는 코드라면 컴파일 하지 않고 인터프리팅하는 것이 유리하다.
  • JIT 컴파일러를 사용하는 JVM들은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하고 일정 정도를 넘을때에만 컴파일을 수행한다.
  • 자바에선 자바 컴파일러가 자바 프로그램 코드를 바이트 코드로 변환한 다음, 실제 바이트 코드를 실행하는 시점에서 자바 가상 머신(JVM, 정확히는 JRE)이 바이트 코드를 JIT 컴파일을 통해 기계어로 변환한다.

인터프리터(interpreter)

  • 프로그램을 실행할 때 한 문장씩 번역한다.
  • 한번에 한문장씩 번역 후 실행 시키기 때문에 실행 시간이 느리다.
  • 컴파일러와 같은 오브젝트 코드 생성 과정이 없어서 메모리 효율이 좋다.
  • 프로그램을 실행시키고 나서 오류를 발견하면 바로 실행을 중지 시킨다. 실행 후에 오류를 알 수 있다.
  • Python, Ruby, Javascript

 

컴파일러(compiler)

  • 전체 파일을 스캔하여 한꺼번에 번역한다.
  • 초기 스캔시간이 오래 걸리지만, 한번 실행 파일이 만들어지고 나면 빠르다.
  • 기계어 번역과정에서 더 많은 메모리를 사용한다.
  • 전체 코드를 스캔하는 과정에서 모든 오류를 한꺼번에 출력해주기 때문에 실행 전에 오류를 알 수 있다.
  • C, C++, JAVA

 🏈JVM 구성 요소

  • 클래스 로더(Class Loader)
  • 실행 엔진 (Execution Engine)
  • 인터프리터 (Interpreter)
  • JIT 컴파일러 (Just In Time Compiler)
  • 가비지 콜렉터 (Garbage Collector)
  • 런타임 데이터 영역 (Runtime Data Area)

 

클래스 로더 (Class Loader)

  • JVM 내로 클래스 파일(*.class)을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈이다.
  • 런 타임시 동적으로 클래스를 로드하고 jar 파일 내 저장된 클래스들을 JVM 위에 탑재한다.
  • 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크하는 역할을 한다.

 

실행 엔진(Execution Engine)

  • 클래스를 실행시키는 역할이다.
  • 클래스 로더가 JVM내의 런타임 데이터 영역에 바이트 코드를 배치시키고, 이것은 실행 엔진에 의해 실행된다.
  • 자바 바이트 코드(*.class)는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다.
  • 그래서 실행 엔진은 이와 같은 바이트 코드를 실제로 JVM 내부에서 기계가 실행할 수 있는 형태로 변경한다.

 

인터프리터 (Interpreter)

  • 실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
  • 하지만 한 줄씩 수행하기 때문에 느리다는 단점이 있다.
  • JIT 컴파일러, 가비지 콜렉터, 런타임 데이터 영역이 인터프리터에 속한다.

 

→ JIT 컴파일러 (Just In Time Compiler)

  • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변경하고, 이후에는 해당 더 이상 인터프리팅 하지 않고 기계어로 직접 실행하는 방식이다. 

 

가비지 콜렉터 (Garbage Collector)

  • 더이상 사용되지 않는 인스턴스를 찾아 메모리에서 삭제한다.

 

런타임 데이터 영역 (Runtime Data Area)

  • 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간을 말한다.

 

 


 🏈JDK와 JRE의 차이

JDK  = Java Development Kit (자바 개발 키트)

  • Java 를 사용하기 위해 필요한 모든 기능을 갖춘 Java용 SDK (Software Development Kit)이다.
  • JDK 는 JRE를 포함하고 있다.
  • JDK에는 JRE에 있는 것 뿐만 아니라 컴파일러(javac)와 jdb, javadoc 과 같은 도구도 있다.
  • 즉, JDK는 프로그램을 생성, 실행, 컴파일할 수 있다.

 

JRE = Java Runtime Environment (자바 런타임 환경)

  • JVM + 자바 클래스 라이브러리(Java Class Library) 등으로 구성되어 있다.
  • 컴파일 된 Java 프로그램을 실행하는데 필요한 패키지이다.
⭐ JDK는 JRE, JVM을 모두 포함하는 포괄적 키트이다.
⭐ JDK는 자바 프로그램 실행, 컴파일, 개발할 수 있게 해주는 도구이다.
⭐ JRE는 자바 프로그램을 실행할 수 있게 해주는 도구이다.