경주장

1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. 본문

JAVA/whiteship_live-study

1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.

달리는치타 2022. 1. 6. 01:50

매주 일요일목요일...을 마감으로 생각해서 백기선님의 온라인 자바 스터디를 진행하겠습니다.

 

GitHub - whiteship/live-study: 온라인 스터디

온라인 스터디. Contribute to whiteship/live-study development by creating an account on GitHub.

github.com


목표

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

학습할 것

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

자바 가상 머신(Java Virtual Machine, JVM)은 자바 바이트코드를 실행할 수 있는 주체이다. 일반적으로 인터프리터나 JIT 컴파일 방식으로 다른 컴퓨터 위에서 바이트코드를 실행할 수 있도록 구현되나 jop 자바 프로세서처럼 하드웨어와 소프트웨어를 혼합해 구현하는 경우도 있다. (이론적으로는 100% 하드웨어 구현도 가능하나 비효율적이다) 자바 바이트코드는 플랫폼에 독립적이며 모든 자바 가상 머신은 자바 가상 머신 규격에 정의된 대로 자바 바이트코드를 실행한다. 따라서 표준 자바 API까지 동일한 동작을 하도록 구현한 상태에서는 이론적으로 모든 자바 프로그램은 CPU나 운영 체제의 종류와 무관하게 동일하게 동작할 것을 보장한다. - 위키피디아

 

https://youtu.be/G1ubVOl9IBw

 

 

C언어의 Compile, Linking and Excution과정은 다음과 같다.

컴파일과정에서 컴파일러는 각 .c 파일을통해 Machine code인 .obj파일을 생성한다.

링커는 obj 파일들을 엮어 실행파일을 생성한다.

 

실행 과정에서 로더는 실행파일을 메모리에 올린다.


자바의 컴파일 & 링킹과정은 아래와 같다.

자바에서는 .java 파일들이 컴파일러(javac)를 통해 바이트코드(.class)로 변환된다.

 

RAM에 미리 올라와 있는 JVM

  1. Class Loader를 통해 바이트코드를 메모리에 올린다.
  2. Byte Code Verifier를 통해 바이트코드의 보안상 문제를 확인한다.
  3. Excution Engine은 바이트코드를 Native Machine Code로 convert한다.

3과정이 자바가 JIT(Just In Time) 컴파일을 활용한다는 의미이며 자바가 C/C++에비해 상대적으로 느린 이유이다.

 


태초의 문제

C/C++는 컴파일 플랫폼과 타겟 플램폼이 다를 경우 프로그램이 동작하지 않는다.

 

해결법 1 

크로스 컴파일(Cross Compile)!

  • 타겟 플랫폼에 맞춰서 컴파일

 

해결법 2

JVM으로 문제를 해결

  • 자바 바이트코드는 타겟 플랫폼에 상관 없이 JVM 위에서 동작한다.
  • 물론 JVM은 타겟 플랫폼에 의존한다.

 

 

WORA - Write Once, Run AnyWhere

 

자바의 야심

웹으로 .class 파일만 전달하면 

웹브라우저에 설치된 JVM이 실행

 

자바 코드가 실행 되기 까지

플랫폼에 Dependent해야 하는것은 잘 따져보면 JVM부분이다!


JVM의 특징

  • 레지스터가 아닌 스택 기반의 가상 머신 - 자바의 야심과 관련이 있다
    • 레지스터는 실행환경에 종속적임
  • 단일 상속 형태의 객체 지향 프로그래밍을 가상 머신 수준에서 구현
  • 포인터를 지원하되 C와 같이 주소 값을 임의로 조작이 가능한 포인터 연산이 불가능
  • 가비지 컬렉션 사용
  • 모든 기본 타입의 정의를 명확히 함으로써 플랫폼 독립성 보장

자바 클래스로더

자바 클래스 로더  자바 클래스 자바 가상 머신(JVM) 中 런타임 데이터 영역으로 동적 로드하는 자바 런타임 환경(JRE)의 일부이다.

클래스 로더에는 세 가지 주요 유형이 있습니다.

-부트 스트랩 클래스 로더 (java.lang과 같은 모든 자바 코어 라이브러리로드)

-확장 클래스 로더 (jar 파일에 정의 된 클래스를 $ JAVA_HOME $ \ lib \ ext)

-시스템 클래스 로더 (CLASSPATH에서 클래스로드) *

 

 

클래스 로더를 확인해보자!

=> 실행결과

Runner와 SpringApplication의 클래스로더는 시스템클래스로더이고 ArrayList의 클래스로더는 부트스트랩클래스 로더이다.

 

What if a class can not be found and loaded => ClassNotFoundException!

 


JIT 컴파일 이란??

전통적인 컴파일 방식인 정적 컴파일 방식과 인터프리트 방식의 사이에 있는 컴파일 방식

바이트코드 컴파일러와 JVM의 JIT 컴파일가가 각각의 장점을 활용하는샘이다.

 

 JIT는 정적 컴파일러 만큼 빠르면서 인터프러터 언어의 빠른 응답속도를 추구하기 위해 사용한다.

 

 

의미없는 코드를 제거 하는 등의 런타임에서만 알 수있는 소중한 정보들을 활용해서 최적화를 한다.


JVM 구성 요소

 런타임 데이터 영역

 

스레드 공유

  • 매서드 영역 - 바이트코드, 클래스 정보, static 키워드로 생성한 공유변수 
  • 힙 영억 - 동적으로 생성된 객체가 저장, GC의 대상이 된다.

 

개별 스레드 마다 존재

  • 스택영역 - 지역변수, 메서드의 매개변수, 임시적으로 사용되는 변수, 메서드의 정보가 저장
  • PC레지스터 영역 - 현재 수행중인 JVM 명령어의 주소를 저장
  • 네이티브 메서드 스택 - JAVA가 아닌 다른 언어를 위한 공간


JVM, JRE, JDK가 뭔가요??

JDK JRE 차이점 JDK Java 프로그램을 개발하고 실행할 수있는 환경을 제공하는 반면 JRE Java 프로그램을 실행하는 환경 만 제공한다는 것입니다. 요약하면, JDK는 JDE와 개발 도구의 조합이며, JRE는 JVM과 라이브러리 파일의 조합입니다.