순간을 성실히, 화려함보단 꾸준함을

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

백기선님과 함께 하는 자바 스터디

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

폭발토끼 2021. 5. 1. 23:19

시작하기 앞서 알고리즘 문제를 푸는 것 정말 중요한일이지만 애초에 왜 이 블로그를 개설하였는지 생각해보았습니다. 단순히 알고리즘 관련 블로그가 아닌 저처럼 불완전한 컴공학생들을 위해 같이 지식을 쌓고 부족한점을 서로서로 채워 보자라는 취지에서 만들었었습니다. 그러나 언제부턴가 나태해지기 시작했고 더이상 미룰수 없다는 생각이 들어 '개발'을 위한 토대를 쌓아 올리는 일들을 해보려고 합니다. 전 백엔드 개발자가 되고 싶습니다. 다양한 프레임워크 중 스프링을 배워보고 싶으며 이를 위해선 가장 기본적인 JAVA를 공부하여 시작하려고 합니다. 몇명이나 이 글들을 보실지는 모르겠지만 부족한 글 읽어주시고 댓글까지 남겨주셔서 채워주시면 감사한 마음을 가지며 열심히 해보겠습니다.

목표

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

학습할 것

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

JVM이란 무엇인가

JVM(JAVA VIRTUAL MACHINE) 자바 가상 머신이라는 뜻
자바 가상 머신은 자바 프로그램이 실행 될 수 있도록 도와주는 역할을 한다.
이 JVM 때문에 운영체제에 구속되지 않고 자바를 실행 시킬 수 있는 것이다.
JVM의 구성은 크게 4가지부분으로 나뉘게 된다

  1. Class Loader
  2. Execution Engine
  3. Garbage Collector
  4. Runtime Data Area

1.Class Loader

.java 파일을 자바컴파일러가 컴파일을 하게 되면 .class(바이트코드) 파일이 생성된다. 이때 JVM이 이 .class 파일들을 운영체제로부터 할당받은 메모리 영역(Runtime Data Area)에 적재하는 역할을 Class Loader가 수행하게 된다.

2.Execution Engine

Runtime Data Area에 적재되어 있는 .class(바이트코드) 파일들을 기계어로 변역하여 실행시키는 역할을 한다.
이때 두가지 방법을 혼합해서 실행시키게 된다.

  1. Interpreter 방식
  • 바이트코드를 한줄씩 읽어들여서 실행시키는 방법. 속도가 느리다는 단점이 존재한다.
  1. JIT(Just In Time) 컴파일 방식
  • 바이트코드를 JIT컴파일러를 사용하여 프로그램을 실제 실행하는 시점에 각 OS에 맞는 Native Code로 변환하는 방법이다. 이때문에 속도가 개선되는 장점을 얻게 되었다. 그러나 Native Code로 변환하는 것 또한 비용이 소묘된다. 따라서 JVM은 모든 코드를 Native Code로 변환하는 것이 아닌 적절하게 혼합하는 방식으로 명령어들을 실행시킨다.

3. Garbage Collector

Heap 영역에 적재되어 있는 객체들 중에서 참조되지 않은 객체들을 살피면서 제거하는 역할을 수행한다.
왜냐면 JAVA는 개발자가 직접 생성된 객체들을 메모리에서 제거하는 것이 아닌 JVM에게 그 책임을 넘겼기 때문이다.
더욱 더 자세한 내용을 참고하고 싶은 사람은 이 링크를 타고 공부하길 바란다.

4. Runtime Data Area

JVM이 자바 프로그램을 실행하기 위해서 운영체제로부터 할당받는 메모리 영역을 나타낸다.
Method Area,Heap Area,Stack Area,PC register,Native Method Stack 이렇게 5구간으로 나뉜다.
이 또한 자세한 정보를 얻고 싶으면 링크를 타고 공부해보자

컴파일 하는 방법

.java 파일을 컴파일을 하게 된다면 .class 파일이 생성이 된다. 이 과정을 하는 방법을 알아보자

- 참고사항

  1. 자바 11 버전으로 컴파일을 하고 이 파일을 자바 8로 실행을 하였을때
  2. 자바 8버전으로 컴파일을 하고 이 파일을 자바 11로 실행을 하였을때

둘 중 몇번이 에러가 발생할까요??
바로 1입니다.
근데 우리가 한번 예시를 들어보면 A라는 사람은 자바 12버전을 기반으로 개발하였고 B라는 사람은 자바 8버전을 기반으로 개발을 하였는데 이를 합쳐서 패키징하려고 하면 에러가 발생하는게 맞는게 아니냐??그럼 대체 어떻게 일일히 이를 다 맞추어줘야 하는가? 라는 의문점이 생기실 수 있습니다. 이를 해결할 수 있는 방법이 있는데 바로 "자바 컴파일러 옵션"입니다.
자바 12버전으로 개발하였어도 8버전으로 컴파일하고 실행하고 싶을땐 javac 의 옵션인 source 와 target을 이용하면 됩니다.

javac -source : javac -source release 옵션을 사용하여 소스 파일에 적용된 Java 버전을 컴파일러에 알릴 수 있습니다.
javac -target : javac -target release 옵션을 사용하면 컴파일러는 특정 Java 가상 머신 (VM) 버전에 대한 .class 파일을 생성할 수 있습니다.

만약 1.6에서 컴파일 하지만 1.5에서 실행되게끔 하고 싶으면

C:>javac -source 1.5 -target 1.5 -bootclasspath C:\\jdk1.6.0\\lib\\rt.jar -extdirs "" OldCode.java

라고 명령어를 입력해주시면 됩니다. 다만 target뒤에 rt.jar 이 위치한 경로를 입력해주어야 합니다. 이를 입력해 주지 않으면

warning: \[options\] bootstrap class path not set in conjunction with -source 1.5

이러한 경고메세지가 출력이 됩니다.

바이트코드란 무엇인가

자바 가상 머신이 이해할 수 있는 .class 파일들의 소스들을 의미한다. 왜 바이트코드라고 명칭이 붙여지게 되었냐면 명령코드들의 크기가 1byte이기 때문에 바이트코드라고 불린다.
* 주의할점
바이트 코드가 아닌 바이트코드이다. 띄어쓰면 안된다.

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

자바 프로그램은 실행중인 런타임에 기계언어로 변환하는 역할을 수행합니다. JIT 컴파일러는 자주 실행되거나 반복되는 코드의 변환 내용을 캐싱하여 기계어로 변환할 필요가 없이 빠르게 실행하도록 도와주는 역할을 합니다.

JDK와 JRE의 차이

JRE(Java Runtime Enviroment) : 컴파일된 자바 프로그램을 실행시킬 수 있는 자바 환경을 뜻함

  • JVM이 자바 프로그램을 동작시킬때 필요한 라이브러리 파일들을 가지고 있음
  • 자바 프로그램을 실행시키기 위해선 반드시 JRE를 설치해야한다.

JDK(Java Development Kit) : 자바 프로그래밍시 필요한 컴파일러와 JRE 를 포함

  • JDK = JRE + @
  • javac 는 JDK에 속해 있다.
    * java9부터는 JRE가 없어지고 JDK만 배포한다.
    why? 결국 JRE는 일종의 중복이 된다. 그래서 JDK만 배포하고 있다.